Module Name:    src
Committed By:   snj
Date:           Tue May 19 05:09:02 UTC 2015

Modified Files:
        src/sys/dev/pci [netbsd-7]: if_wm.c if_wmreg.h if_wmvar.h

Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #784):
        sys/dev/pci/if_wm.c: revision 1.321
        sys/dev/pci/if_wmreg.h: revision 1.71
        sys/dev/pci/if_wmvar.h: 1.24 via patch
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/NICs.


To generate a diff of this commit:
cvs rdiff -u -r1.289.2.6 -r1.289.2.7 src/sys/dev/pci/if_wm.c
cvs rdiff -u -r1.60.2.2 -r1.60.2.3 src/sys/dev/pci/if_wmreg.h
cvs rdiff -u -r1.19.2.2 -r1.19.2.3 src/sys/dev/pci/if_wmvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_wm.c
diff -u src/sys/dev/pci/if_wm.c:1.289.2.6 src/sys/dev/pci/if_wm.c:1.289.2.7
--- src/sys/dev/pci/if_wm.c:1.289.2.6	Sun Apr 19 06:50:22 2015
+++ src/sys/dev/pci/if_wm.c	Tue May 19 05:09:02 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.289.2.6 2015/04/19 06:50:22 riz Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.289.2.7 2015/05/19 05:09:02 snj 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.289.2.6 2015/04/19 06:50:22 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.289.2.7 2015/05/19 05:09:02 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -658,10 +658,14 @@ static int32_t	wm_read_ich8_data(struct 
 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 *);
 
@@ -1823,9 +1827,15 @@ wm_attach(device_t parent, device_t self
 		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;
@@ -1885,11 +1895,13 @@ wm_attach(device_t parent, device_t self
 	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
@@ -8511,6 +8523,102 @@ wm_nvm_read_ich8(struct wm_softc *sc, in
 	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 */
 
 /*
@@ -8623,6 +8731,18 @@ wm_nvm_is_onboard_eeprom(struct wm_softc
 	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
  *
@@ -8716,6 +8836,8 @@ wm_nvm_read(struct wm_softc *sc, int wor
 	    || (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)

Index: src/sys/dev/pci/if_wmreg.h
diff -u src/sys/dev/pci/if_wmreg.h:1.60.2.2 src/sys/dev/pci/if_wmreg.h:1.60.2.3
--- src/sys/dev/pci/if_wmreg.h:1.60.2.2	Wed Mar 18 04:39:15 2015
+++ src/sys/dev/pci/if_wmreg.h	Tue May 19 05:09:02 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wmreg.h,v 1.60.2.2 2015/03/18 04:39:15 snj Exp $	*/
+/*	$NetBSD: if_wmreg.h,v 1.60.2.3 2015/05/19 05:09:02 snj Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -890,6 +890,11 @@ struct livengood_tcpip_ctxdesc {
 
 #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
@@ -917,15 +922,21 @@ struct livengood_tcpip_ctxdesc {
 #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 */
@@ -988,6 +999,34 @@ struct livengood_tcpip_ctxdesc {
  */
 #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 */

Index: src/sys/dev/pci/if_wmvar.h
diff -u src/sys/dev/pci/if_wmvar.h:1.19.2.2 src/sys/dev/pci/if_wmvar.h:1.19.2.3
--- src/sys/dev/pci/if_wmvar.h:1.19.2.2	Fri Nov  7 21:34:56 2014
+++ src/sys/dev/pci/if_wmvar.h	Tue May 19 05:09:02 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wmvar.h,v 1.19.2.2 2014/11/07 21:34:56 snj Exp $	*/
+/*	$NetBSD: if_wmvar.h,v 1.19.2.3 2015/05/19 05:09:02 snj 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() fininsed successfully */
+#define	WM_F_EEPROM_INVM	0x01000000 /* NVM is iNVM */
 
 typedef enum {
 	WM_T_unknown		= 0,

Reply via email to