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 I217 (and I218) support.



details:   https://anonhg.NetBSD.org/src/rev/dd48d05847f9
branches:  trunk
changeset: 787101:dd48d05847f9
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Sun Jun 02 09:36:22 2013 +0000

description:
Add I217 (and I218) support.
- The name of I217 is similar to I210, but the function is rather similar to
  PCH2.
- Not tested well. Tested with my own Intel DQ87PG which has I217LM onboard.
- It seems that PCH2 and PCH_LPT specific function for RAL should be written.
- Quick hack for the NVM checksum mismatch. if_wm.c currently has no
  wm_write_eeprom(), so it cannot update NVM's "updated bit". To avoid this
  problem, check only the last 12bits of the checksum. My own DQ87PG's
  updated bit is not set, and I could avoid the problem using with this
  hack.

diffstat:

 sys/dev/pci/if_wm.c    |  108 +++++++++++++++++++++++++++++++++++++++---------
 sys/dev/pci/if_wmvar.h |    4 +-
 2 files changed, 87 insertions(+), 25 deletions(-)

diffs (truncated from 386 to 300 lines):

diff -r 0f36122ca783 -r dd48d05847f9 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Sun Jun 02 09:13:27 2013 +0000
+++ b/sys/dev/pci/if_wm.c       Sun Jun 02 09:36:22 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.248 2013/04/21 19:59:41 msaitoh Exp $      */
+/*     $NetBSD: if_wm.c,v 1.249 2013/06/02 09:36:22 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.248 2013/04/21 19:59:41 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.249 2013/06/02 09:36:22 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1045,6 +1045,18 @@
        { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_I211_COPPER,
          "I211 Ethernet (COPPER)",
          WM_T_I211,            WMP_F_1000T },
+       { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_I217_V,
+         "I217 V Ethernet Connection",
+         WM_T_PCH_LPT,         WMP_F_1000T },
+       { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_I217_LM,
+         "I217 LM Ethernet Connection",
+         WM_T_PCH_LPT,         WMP_F_1000T },
+       { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_I218_V,
+         "I218 V Ethernet Connection",
+         WM_T_PCH_LPT,         WMP_F_1000T },
+       { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_I218_LM,
+         "I218 LM Ethernet Connection",
+         WM_T_PCH_LPT,         WMP_F_1000T },
        { 0,                    0,
          NULL,
          0,                    0 },
@@ -1347,7 +1359,8 @@
                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_PCH2)) {
+                   && (sc->sc_type != WM_T_PCH2)
+                   && (sc->sc_type != WM_T_PCH_LPT)) {
                        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,
@@ -1516,7 +1529,8 @@
        CSR_READ(sc, WMREG_RXERRC);
 
        /* get PHY control from SMBus to PCIe */
-       if ((sc->sc_type == WM_T_PCH) || (sc->sc_type == WM_T_PCH2))
+       if ((sc->sc_type == WM_T_PCH) || (sc->sc_type == WM_T_PCH2)
+           || (sc->sc_type == WM_T_PCH_LPT))
                wm_smbustopci(sc);
 
        /*
@@ -1536,6 +1550,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                if (wm_check_mng_mode(sc) != 0)
                        wm_get_hw_control(sc);
                break;
@@ -1612,6 +1627,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                /* FLASH */
                sc->sc_flags |= WM_F_EEPROM_FLASH | WM_F_SWFWHW_SYNC;
                memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, WM_ICH8_FLASH);
@@ -1762,6 +1778,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                /* XXX The funcid should be checked on some devices */
                apme_mask = WUC_APME;
                eeprom_data = CSR_READ(sc, WMREG_WUC);
@@ -1864,7 +1881,8 @@
         */
        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_PCH2 || sc->sc_type == WM_T_82573
+           || sc->sc_type == WM_T_PCH2 || sc->sc_type == WM_T_PCH_LPT
+           || sc->sc_type == WM_T_82573
            || sc->sc_type == WM_T_82574 || sc->sc_type == WM_T_82583) {
                /* STATUS_TBIMODE reserved/reused, can't rely on it */
                wm_gmii_mediainit(sc, wmp->wmp_product);
@@ -1953,6 +1971,7 @@
        case WM_T_ICH9:
        case WM_T_ICH10:
        case WM_T_PCH2: /* PCH2 supports 9K frame size */
+       case WM_T_PCH_LPT:
                /* XXX limited to 9234 */
                sc->sc_ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU;
                break;
@@ -4054,6 +4073,7 @@
                break;
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                sc->sc_pba = PBA_26K;
                break;
        default:
@@ -4168,6 +4188,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                reg = CSR_READ(sc, WMREG_CTRL) | CTRL_RST;
                if (wm_check_reset_block(sc) == 0) {
                        /*
@@ -4277,6 +4298,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                wm_lan_init_done(sc);
                break;
        default:
@@ -4410,6 +4432,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                if (wm_check_mng_mode(sc) != 0)
                        wm_get_hw_control(sc);
                break;
@@ -4592,6 +4615,7 @@
                case WM_T_ICH10:
                case WM_T_PCH:
                case WM_T_PCH2:
+               case WM_T_PCH_LPT:
                        /*
                         * Set the mac to wait the maximum time between each
                         * iteration and increase the max iterations when
@@ -4932,6 +4956,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                for (i = 0; i < WM_ICH8_LAN_INIT_TIMEOUT; i++) {
                        reg = CSR_READ(sc, WMREG_STATUS);
                        if ((reg & STATUS_LAN_INIT_DONE) != 0)
@@ -5013,6 +5038,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                if (sc->sc_type >= WM_T_PCH) {
                        reg = CSR_READ(sc, WMREG_STATUS);
                        if ((reg & STATUS_PHYRA) != 0)
@@ -5297,8 +5323,12 @@
        return 0;
 }
 
-#define EEPROM_CHECKSUM                0xBABA
-#define EEPROM_SIZE            0x0040
+#define NVM_CHECKSUM                   0xBABA
+#define EEPROM_SIZE                    0x0040
+#define NVM_COMPAT                     0x0003
+#define NVM_COMPAT_VALID_CHECKSUM      0x0001
+#define NVM_FUTURE_INIT_WORD1                  0x0019
+#define NVM_FUTURE_INIT_WORD1_VALID_CHECKSUM   0x0040
 
 /*
  * wm_validate_eeprom_checksum
@@ -5308,8 +5338,9 @@
 static int
 wm_validate_eeprom_checksum(struct wm_softc *sc)
 {
-       uint16_t checksum;
+       uint16_t checksum, valid_checksum;
        uint16_t eeprom_data;
+       uint16_t csum_wordaddr;
        int i;
 
        checksum = 0;
@@ -5318,15 +5349,26 @@
        if (sc->sc_type == WM_T_I211)
                return 0;
 
+       if (sc->sc_type == WM_T_PCH_LPT) {
+               printf("[PCH_LPT]");
+               csum_wordaddr = NVM_COMPAT;
+               valid_checksum = NVM_COMPAT_VALID_CHECKSUM;
+       } else {
+               csum_wordaddr = NVM_FUTURE_INIT_WORD1;
+               valid_checksum = NVM_FUTURE_INIT_WORD1_VALID_CHECKSUM;
+       }
+
 #ifdef WM_DEBUG
        /* Dump EEPROM image for debug */
        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_PCH2)) {
-               wm_read_eeprom(sc, 0x19, 1, &eeprom_data);
-               if ((eeprom_data & 0x40) == 0) {
-                       DPRINTF(WM_DEBUG_NVM,("%s: NVM need to be updated\n",
-                               device_xname(sc->sc_dev)));
+           || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)) {
+               wm_read_eeprom(sc, csum_wordaddr, 1, &eeprom_data);
+               if ((eeprom_data & valid_checksum) == 0) {
+                       DPRINTF(WM_DEBUG_NVM,
+                           ("%s: NVM need to be updated (%04x != %04x)\n",
+                               device_xname(sc->sc_dev), eeprom_data,
+                                   valid_checksum));
                }
        }
 
@@ -5350,8 +5392,19 @@
                checksum += eeprom_data;
        }
 
-       if (checksum != (uint16_t) EEPROM_CHECKSUM)
-               return 1;
+       if (checksum != (uint16_t) NVM_CHECKSUM) {
+#ifdef WM_DEBUG
+               printf("%s: NVM checksum mismatch (%04x != %04x)\n",
+                   device_xname(sc->sc_dev), checksum, NVM_CHECKSUM);
+#endif
+               /*
+                * XXX quick hack for non-updated NVM.
+                * Check only last 12bit until wm_write_eeprom() will be
+                * implemented.
+                */
+               if ((checksum & 0x0fff) != ((uint16_t)NVM_CHECKSUM & 0x0fff))
+                       return 1;
+       }
 
        return 0;
 }
@@ -5374,7 +5427,7 @@
 
        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_PCH2))
+           || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT))
                rv = wm_read_eeprom_ich8(sc, word, wordcnt, data);
        else if (sc->sc_flags & WM_F_EEPROM_EERDEEWR)
                rv = wm_read_eeprom_eerd(sc, word, wordcnt, data);
@@ -5654,7 +5707,7 @@
 
        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_PCH2)) {
+           || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)) {
                hash = (enaddr[4] >> ich8_lo_shift[sc->sc_mchash_type]) |
                    (((uint16_t) enaddr[5]) << ich8_hi_shift[sc->sc_mchash_type]);
                return (hash & 0x3ff);
@@ -5702,7 +5755,8 @@
        if (sc->sc_type == WM_T_ICH8)
                size = WM_RAL_TABSIZE_ICH8 -1;
        else if ((sc->sc_type == WM_T_ICH9) || (sc->sc_type == WM_T_ICH10)
-           || (sc->sc_type == WM_T_PCH) || (sc->sc_type == WM_T_PCH2))
+           || (sc->sc_type == WM_T_PCH) || (sc->sc_type == WM_T_PCH2)
+           || (sc->sc_type == WM_T_PCH_LPT))
                size = WM_RAL_TABSIZE_ICH8;
        else if (sc->sc_type == WM_T_82575)
                size = WM_RAL_TABSIZE_82575;
@@ -5718,7 +5772,7 @@
 
        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_PCH2))
+           || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT))
                size = WM_ICH8_MC_TABSIZE;
        else
                size = WM_MC_TABSIZE;
@@ -5745,7 +5799,8 @@
                reg = (hash >> 5);
                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_PCH2))
+                   || (sc->sc_type == WM_T_PCH2)
+                   || (sc->sc_type == WM_T_PCH_LPT))
                        reg &= 0x1f;
                else
                        reg &= 0x7f;
@@ -6098,6 +6153,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                rv = wm_get_swfwhw_semaphore(sc);
                break;
        default:
@@ -6184,6 +6240,7 @@
        case WM_T_ICH10:
        case WM_T_PCH:
        case WM_T_PCH2:
+       case WM_T_PCH_LPT:
                /* generic reset */
                CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET);
                delay(100);
@@ -6221,6 +6278,7 @@
        case WM_T_ICH10:



Home | Main Index | Thread Index | Old Index