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 iNVM (integrated Non-Volatile Memory...



details:   https://anonhg.NetBSD.org/src/rev/d54351f5974f
branches:  trunk
changeset: 338270:d54351f5974f
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Sat May 16 22:41:59 2015 +0000

description:
Add support iNVM (integrated Non-Volatile Memory) for I21[01]. This change
fixes a bug that a MAC address is wrongly set on iNVM machines and NICs.
Tested with Shuttle DS57U(iNVM based) and other non iNVM based I210 machines.

diffstat:

 sys/dev/pci/if_wm.c    |  138 ++++++++++++++++++++++++++++++++++++++++++++++--
 sys/dev/pci/if_wmreg.h |   43 ++++++++++++++-
 sys/dev/pci/if_wmvar.h |    3 +-
 3 files changed, 173 insertions(+), 11 deletions(-)

diffs (296 lines):

diff -r 615da0fb2c2c -r d54351f5974f sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Sat May 16 22:24:41 2015 +0000
+++ b/sys/dev/pci/if_wm.c       Sat May 16 22:41:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.320 2015/05/04 10:10:42 msaitoh Exp $      */
+/*     $NetBSD: if_wm.c,v 1.321 2015/05/16 22:41:59 msaitoh Exp $      */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -81,7 +81,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.320 2015/05/04 10:10:42 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.321 2015/05/16 22:41:59 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -667,10 +667,14 @@
 static int32_t wm_read_ich8_byte(struct wm_softc *, uint32_t, uint8_t *);
 static int32_t wm_read_ich8_word(struct wm_softc *, uint32_t, uint16_t *);
 static int     wm_nvm_read_ich8(struct wm_softc *, int, int, uint16_t *);
+/* iNVM */
+static int     wm_nvm_read_word_invm(struct wm_softc *, uint16_t, uint16_t *);
+static int     wm_nvm_read_invm(struct wm_softc *, int, int, uint16_t *);
 /* Lock, detecting NVM type, validate checksum and read */
 static int     wm_nvm_acquire(struct wm_softc *);
 static void    wm_nvm_release(struct wm_softc *);
 static int     wm_nvm_is_onboard_eeprom(struct wm_softc *);
+static int     wm_nvm_get_flash_presence_i210(struct wm_softc *);
 static int     wm_nvm_validate_checksum(struct wm_softc *);
 static int     wm_nvm_read(struct wm_softc *, int, int, uint16_t *);
 
@@ -1841,9 +1845,15 @@
                break;
        case WM_T_I210:
        case WM_T_I211:
-               wm_nvm_set_addrbits_size_eecd(sc);
-               sc->sc_flags |= WM_F_EEPROM_FLASH_HW;
-               sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_LOCK_SWFW;
+               if (wm_nvm_get_flash_presence_i210(sc)) {
+                       wm_nvm_set_addrbits_size_eecd(sc);
+                       sc->sc_flags |= WM_F_EEPROM_FLASH_HW;
+                       sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_LOCK_SWFW;
+               } else {
+                       sc->sc_nvm_wordsize = INVM_SIZE;
+                       sc->sc_flags |= WM_F_EEPROM_INVM;
+                       sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_LOCK_SWFW;
+               }
                break;
        default:
                break;
@@ -1903,11 +1913,13 @@
        else {
                aprint_verbose_dev(sc->sc_dev, "%u words ",
                    sc->sc_nvm_wordsize);
-               if (sc->sc_flags & WM_F_EEPROM_FLASH_HW) {
+               if (sc->sc_flags & WM_F_EEPROM_INVM)
+                       aprint_verbose("iNVM\n");
+               else if (sc->sc_flags & WM_F_EEPROM_FLASH_HW)
                        aprint_verbose("FLASH(HW)\n");
-               } else if (sc->sc_flags & WM_F_EEPROM_FLASH) {
+               else if (sc->sc_flags & WM_F_EEPROM_FLASH)
                        aprint_verbose("FLASH\n");
-               } else {
+               else {
                        if (sc->sc_flags & WM_F_EEPROM_SPI)
                                eetype = "SPI";
                        else
@@ -8568,6 +8580,102 @@
        return error;
 }
 
+/* iNVM */
+
+static int
+wm_nvm_read_word_invm(struct wm_softc *sc, uint16_t address, uint16_t *data)
+{
+       int32_t  rv = 0;
+       uint32_t invm_dword;
+       uint16_t i;
+       uint8_t record_type, word_address;
+
+       for (i = 0; i < INVM_SIZE; i++) {
+               invm_dword = CSR_READ(sc, E1000_INVM_DATA_REG(i));
+               /* Get record type */
+               record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
+               if (record_type == INVM_UNINITIALIZED_STRUCTURE)
+                       break;
+               if (record_type == INVM_CSR_AUTOLOAD_STRUCTURE)
+                       i += INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
+               if (record_type == INVM_RSA_KEY_SHA256_STRUCTURE)
+                       i += INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
+               if (record_type == INVM_WORD_AUTOLOAD_STRUCTURE) {
+                       word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
+                       if (word_address == address) {
+                               *data = INVM_DWORD_TO_WORD_DATA(invm_dword);
+                               rv = 0;
+                               break;
+                       }
+               }
+       }
+
+       return rv;
+}
+
+static int
+wm_nvm_read_invm(struct wm_softc *sc, int offset, int words, uint16_t *data)
+{
+       int rv = 0;
+       int i;
+
+       for (i = 0; i < words; i++) {
+               switch (offset + i) {
+               case NVM_OFF_MACADDR:
+               case NVM_OFF_MACADDR1:
+               case NVM_OFF_MACADDR2:
+                       rv = wm_nvm_read_word_invm(sc, offset + i, &data[i]);
+                       if (rv != 0) {
+                               data[i] = 0xffff;
+                               rv = -1;
+                       }
+                       break;
+               case NVM_OFF_CFG2:
+                       rv = wm_nvm_read_word_invm(sc, offset, data);
+                       if (rv != 0) {
+                               *data = NVM_INIT_CTRL_2_DEFAULT_I211;
+                               rv = 0;
+                       }
+                       break;
+               case NVM_OFF_CFG4:
+                       rv = wm_nvm_read_word_invm(sc, offset, data);
+                       if (rv != 0) {
+                               *data = NVM_INIT_CTRL_4_DEFAULT_I211;
+                               rv = 0;
+                       }
+                       break;
+               case NVM_OFF_LED_1_CFG:
+                       rv = wm_nvm_read_word_invm(sc, offset, data);
+                       if (rv != 0) {
+                               *data = NVM_LED_1_CFG_DEFAULT_I211;
+                               rv = 0;
+                       }
+                       break;
+               case NVM_OFF_LED_0_2_CFG:
+                       rv = wm_nvm_read_word_invm(sc, offset, data);
+                       if (rv != 0) {
+                               *data = NVM_LED_0_2_CFG_DEFAULT_I211;
+                               rv = 0;
+                       }
+                       break;
+               case NVM_OFF_ID_LED_SETTINGS:
+                       rv = wm_nvm_read_word_invm(sc, offset, data);
+                       if (rv != 0) {
+                               *data = ID_LED_RESERVED_FFFF;
+                               rv = 0;
+                       }
+                       break;
+               default:
+                       DPRINTF(WM_DEBUG_NVM,
+                           ("NVM word 0x%02x is not mapped.\n", offset));
+                       *data = NVM_RESERVED_WORD;
+                       break;
+               }
+       }
+
+       return rv;
+}
+
 /* Lock, detecting NVM type, validate checksum and read */
 
 /*
@@ -8680,6 +8788,18 @@
        return 1;
 }
 
+static int
+wm_nvm_get_flash_presence_i210(struct wm_softc *sc)
+{
+       uint32_t eec;
+
+       eec = CSR_READ(sc, WMREG_EEC);
+       if ((eec & EEC_FLASH_DETECTED) != 0)
+               return 1;
+
+       return 0;
+}
+
 /*
  * wm_nvm_validate_checksum
  *
@@ -8773,6 +8893,8 @@
            || (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH)
            || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT))
                rv = wm_nvm_read_ich8(sc, word, wordcnt, data);
+       else if (sc->sc_flags & WM_F_EEPROM_INVM)
+               rv = wm_nvm_read_invm(sc, word, wordcnt, data);
        else if (sc->sc_flags & WM_F_EEPROM_EERDEEWR)
                rv = wm_nvm_read_eerd(sc, word, wordcnt, data);
        else if (sc->sc_flags & WM_F_EEPROM_SPI)
diff -r 615da0fb2c2c -r d54351f5974f sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h    Sat May 16 22:24:41 2015 +0000
+++ b/sys/dev/pci/if_wmreg.h    Sat May 16 22:41:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wmreg.h,v 1.70 2015/05/15 07:59:00 msaitoh Exp $    */
+/*     $NetBSD: if_wmreg.h,v 1.71 2015/05/16 22:41:59 msaitoh Exp $    */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -891,6 +891,11 @@
 
 #define WMREG_CRC_OFFSET 0x5f50
 
+#define WMREG_EEC      0x12010
+#define EEC_FLASH_DETECTED (1U << 19)  /* FLASH */
+#define EEC_FLUPD      (1U << 23)      /* Update FLASH */
+
+
 /*
  * NVM related values.
  *  Microwire, SPI, and flash
@@ -918,15 +923,21 @@
 #define NVM_SIZE               0x0040
 #define NVM_WORD_SIZE_BASE_SHIFT 6
 
-#define        NVM_OFF_MACADDR         0x0000  /* MAC address offset */
+#define        NVM_OFF_MACADDR         0x0000  /* MAC address offset 0 */
+#define        NVM_OFF_MACADDR1        0x0001  /* MAC address offset 1 */
+#define        NVM_OFF_MACADDR2        0x0002  /* MAC address offset 2 */
 #define NVM_OFF_COMPAT         0x0003
+#define NVM_OFF_ID_LED_SETTINGS        0x0004
 #define        NVM_OFF_CFG1            0x000a  /* config word 1 */
 #define        NVM_OFF_CFG2            0x000f  /* config word 2 */
 #define        NVM_OFF_EEPROM_SIZE     0x0012  /* NVM SIZE */
+#define        NVM_OFF_CFG4            0x0013  /* config word 4 */
 #define        NVM_OFF_CFG3_PORTB      0x0014  /* config word 3 */
 #define NVM_OFF_FUTURE_INIT_WORD1 0x0019
 #define        NVM_OFF_INIT_3GIO_3     0x001a  /* PCIe Initial Configuration Word 3 */
 #define        NVM_OFF_K1_CONFIG       0x001b  /* NVM K1 Config */
+#define        NVM_OFF_LED_1_CFG       0x001c
+#define        NVM_OFF_LED_0_2_CFG     0x001f
 #define        NVM_OFF_SWDPIN          0x0020  /* SWD Pins (Cordova) */
 #define        NVM_OFF_CFG3_PORTA      0x0024  /* config word 3 */
 #define NVM_OFF_ALT_MAC_ADDR_PTR 0x0037        /* to the alternative MAC addresses */
@@ -989,6 +1000,34 @@
  */
 #define NVM_OFF_LAN_FUNC_82580(x)      ((x) ? (0x40 + (0x40 * (x))) : 0)
 
+/* iNVM Registers for i21[01] */
+#define E1000_INVM_DATA_REG(reg)       (0x12120 + 4*(reg))
+#define INVM_SIZE                      64 /* Number of INVM Data Registers */
+
+/* iNVM default vaule */
+#define NVM_INIT_CTRL_2_DEFAULT_I211   0x7243
+#define NVM_INIT_CTRL_4_DEFAULT_I211   0x00c1
+#define NVM_LED_1_CFG_DEFAULT_I211     0x0184
+#define NVM_LED_0_2_CFG_DEFAULT_I211   0x200c
+#define NVM_RESERVED_WORD              0xffff
+
+#define INVM_DWORD_TO_RECORD_TYPE(dword)       ((dword) & 0x7)
+#define INVM_DWORD_TO_WORD_ADDRESS(dword)      (((dword) & 0x0000FE00) >> 9)
+#define INVM_DWORD_TO_WORD_DATA(dword)         (((dword) & 0xFFFF0000) >> 16)
+
+#define INVM_UNINITIALIZED_STRUCTURE           0x0
+#define INVM_WORD_AUTOLOAD_STRUCTURE           0x1
+#define INVM_CSR_AUTOLOAD_STRUCTURE            0x2
+#define INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE   0x3
+#define INVM_RSA_KEY_SHA256_STRUCTURE          0x4
+#define INVM_INVALIDATED_STRUCTURE             0x5
+
+#define INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS        8
+#define INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS  1
+
+/* Word definitions for ID LED Settings */
+#define ID_LED_RESERVED_FFFF 0xFFFF
+
 /* ich8 flash control */
 #define ICH_FLASH_COMMAND_TIMEOUT            5000    /* 5000 uSecs - adjusted */
 #define ICH_FLASH_ERASE_TIMEOUT              3000000 /* Up to 3 seconds - worst case */
diff -r 615da0fb2c2c -r d54351f5974f sys/dev/pci/if_wmvar.h
--- a/sys/dev/pci/if_wmvar.h    Sat May 16 22:24:41 2015 +0000
+++ b/sys/dev/pci/if_wmvar.h    Sat May 16 22:41:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wmvar.h,v 1.23 2014/11/27 11:42:02 msaitoh Exp $    */
+/*     $NetBSD: if_wmvar.h,v 1.24 2015/05/16 22:41:59 msaitoh Exp $    */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -96,6 +96,7 @@
 #define WM_F_WOL               0x00200000
 #define WM_F_EEE               0x00400000 /* Energy Efficiency Ethernet */
 #define WM_F_ATTACHED          0x00800000 /* attach() finished successfully */
+#define        WM_F_EEPROM_INVM        0x01000000 /* NVM is iNVM */
 
 
 /*



Home | Main Index | Thread Index | Old Index