svn commit: r287762 - head/sys/dev/e1000

Sean Bruno sbruno at FreeBSD.org
Sun Sep 13 18:26:10 UTC 2015


Author: sbruno
Date: Sun Sep 13 18:26:05 2015
New Revision: 287762
URL: https://svnweb.freebsd.org/changeset/base/287762

Log:
  Update em(4) with D3162 after testing further on hardware that failed
  to attach with the last version of this commit. This commit fixes
  attach failures on "ICH8" class devices via modifications to
  e1000_init_nvm_params_ich8lan()
  
  -   Fix compiler warning in 80003es2lan.c
  -   Add return value handler for e1000_*_kmrn_reg_80003es2lan
  -   Fix usage of DEBUGOUT
  -   Remove unnecessary variable initializations.
  -   Removed unused variables (complaints from gcc).
  -   Edit defines in 82571.h.
  -   Add workaround for igb hw errata.
  -   Shared code changes for Skylake/I219 support.
  -   Remove unused OBFF and LTR functions.
  
  Tested by some of the folks that reported breakage in previous incarnation.
  Thanks to AllanJude, gjb, gnn, tijl for tempting fate with their machines.
  
  Submitted by:	erj at freebsd.org
  MFC after:	2 weeks
  Differential Revision:	https://reviews.freebsd.org/D3162

Modified:
  head/sys/dev/e1000/e1000_80003es2lan.c
  head/sys/dev/e1000/e1000_82540.c
  head/sys/dev/e1000/e1000_82541.c
  head/sys/dev/e1000/e1000_82542.c
  head/sys/dev/e1000/e1000_82543.c
  head/sys/dev/e1000/e1000_82571.h
  head/sys/dev/e1000/e1000_82575.c
  head/sys/dev/e1000/e1000_82575.h
  head/sys/dev/e1000/e1000_api.c
  head/sys/dev/e1000/e1000_api.h
  head/sys/dev/e1000/e1000_defines.h
  head/sys/dev/e1000/e1000_hw.h
  head/sys/dev/e1000/e1000_i210.c
  head/sys/dev/e1000/e1000_i210.h
  head/sys/dev/e1000/e1000_ich8lan.c
  head/sys/dev/e1000/e1000_ich8lan.h
  head/sys/dev/e1000/e1000_mac.c
  head/sys/dev/e1000/e1000_mac.h
  head/sys/dev/e1000/e1000_nvm.c
  head/sys/dev/e1000/e1000_nvm.h
  head/sys/dev/e1000/e1000_osdep.h
  head/sys/dev/e1000/e1000_phy.c
  head/sys/dev/e1000/e1000_regs.h
  head/sys/dev/e1000/if_igb.c

Modified: head/sys/dev/e1000/e1000_80003es2lan.c
==============================================================================
--- head/sys/dev/e1000/e1000_80003es2lan.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_80003es2lan.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -851,11 +851,17 @@ static s32 e1000_reset_hw_80003es2lan(st
 	e1000_release_phy_80003es2lan(hw);
 
 	/* Disable IBIST slave mode (far-end loopback) */
-	e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
-					&kum_reg_data);
-	kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
-	e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
-					kum_reg_data);
+	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
+				E1000_KMRNCTRLSTA_INBAND_PARAM, &kum_reg_data);
+	if (!ret_val) {
+		kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
+		ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+						 E1000_KMRNCTRLSTA_INBAND_PARAM,
+						 kum_reg_data);
+		if (ret_val)
+			DEBUGOUT("Error disabling far-end loopback\n");
+	} else
+		DEBUGOUT("Error disabling far-end loopback\n");
 
 	ret_val = e1000_get_auto_rd_done_generic(hw);
 	if (ret_val)
@@ -911,11 +917,18 @@ static s32 e1000_init_hw_80003es2lan(str
 		return ret_val;
 
 	/* Disable IBIST slave mode (far-end loopback) */
-	e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
-					&kum_reg_data);
-	kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
-	e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
-					 kum_reg_data);
+	ret_val =
+	    e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
+					    &kum_reg_data);
+	if (!ret_val) {
+		kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
+		ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+						 E1000_KMRNCTRLSTA_INBAND_PARAM,
+						 kum_reg_data);
+		if (ret_val)
+			DEBUGOUT("Error disabling far-end loopback\n");
+	} else
+		DEBUGOUT("Error disabling far-end loopback\n");
 
 	/* Set the transmit descriptor write-back policy */
 	reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0));

Modified: head/sys/dev/e1000/e1000_82540.c
==============================================================================
--- head/sys/dev/e1000/e1000_82540.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_82540.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -66,7 +66,7 @@ static s32  e1000_read_mac_addr_82540(st
 static s32 e1000_init_phy_params_82540(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	phy->addr		= 1;
 	phy->autoneg_mask	= AUTONEG_ADVERTISE_SPEED_DEFAULT;
@@ -329,7 +329,7 @@ static s32 e1000_init_hw_82540(struct e1
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	u32 txdctl, ctrl_ext;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u16 i;
 
 	DEBUGFUNC("e1000_init_hw_82540");
@@ -411,7 +411,7 @@ static s32 e1000_init_hw_82540(struct e1
 static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw)
 {
 	u32 ctrl;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u16 data;
 
 	DEBUGFUNC("e1000_setup_copper_link_82540");
@@ -498,7 +498,7 @@ out:
  **/
 static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u16 nvm_data;
 
 	DEBUGFUNC("e1000_adjust_serdes_amplitude_82540");
@@ -528,7 +528,7 @@ out:
  **/
 static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw)
 {
-	s32  ret_val = E1000_SUCCESS;
+	s32  ret_val;
 	u16 default_page = 0;
 	u16 phy_data;
 

Modified: head/sys/dev/e1000/e1000_82541.c
==============================================================================
--- head/sys/dev/e1000/e1000_82541.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_82541.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -85,7 +85,7 @@ static const u16 e1000_igp_cable_length_
 static s32 e1000_init_phy_params_82541(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	DEBUGFUNC("e1000_init_phy_params_82541");
 
@@ -295,7 +295,7 @@ void e1000_init_function_pointers_82541(
  **/
 static s32 e1000_reset_hw_82541(struct e1000_hw *hw)
 {
-	u32 ledctl, ctrl, icr, manc;
+	u32 ledctl, ctrl, manc;
 
 	DEBUGFUNC("e1000_reset_hw_82541");
 
@@ -317,6 +317,7 @@ static s32 e1000_reset_hw_82541(struct e
 	/* Must reset the Phy before resetting the MAC */
 	if ((hw->mac.type == e1000_82541) || (hw->mac.type == e1000_82547)) {
 		E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_PHY_RST));
+		E1000_WRITE_FLUSH(hw);
 		msec_delay(5);
 	}
 
@@ -359,7 +360,7 @@ static s32 e1000_reset_hw_82541(struct e
 	E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
 
 	/* Clear any pending interrupt events. */
-	icr = E1000_READ_REG(hw, E1000_ICR);
+	E1000_READ_REG(hw, E1000_ICR);
 
 	return E1000_SUCCESS;
 }

Modified: head/sys/dev/e1000/e1000_82542.c
==============================================================================
--- head/sys/dev/e1000/e1000_82542.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_82542.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -317,7 +317,7 @@ static s32 e1000_init_hw_82542(struct e1
 static s32 e1000_setup_link_82542(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	DEBUGFUNC("e1000_setup_link_82542");
 
@@ -565,7 +565,7 @@ static void e1000_clear_hw_cntrs_82542(s
  *
  *  Reads the device MAC address from the EEPROM and stores the value.
  **/
-static s32 e1000_read_mac_addr_82542(struct e1000_hw *hw)
+s32 e1000_read_mac_addr_82542(struct e1000_hw *hw)
 {
 	s32  ret_val = E1000_SUCCESS;
 	u16 offset, nvm_data, i;

Modified: head/sys/dev/e1000/e1000_82543.c
==============================================================================
--- head/sys/dev/e1000/e1000_82543.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_82543.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -900,7 +900,7 @@ static s32 e1000_phy_hw_reset_82543(stru
  **/
 static s32 e1000_reset_hw_82543(struct e1000_hw *hw)
 {
-	u32 ctrl, icr;
+	u32 ctrl;
 	s32 ret_val = E1000_SUCCESS;
 
 	DEBUGFUNC("e1000_reset_hw_82543");
@@ -942,7 +942,7 @@ static s32 e1000_reset_hw_82543(struct e
 
 	/* Masking off and clearing any pending interrupts */
 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
-	icr = E1000_READ_REG(hw, E1000_ICR);
+	E1000_READ_REG(hw, E1000_ICR);
 
 	return ret_val;
 }

Modified: head/sys/dev/e1000/e1000_82571.h
==============================================================================
--- head/sys/dev/e1000/e1000_82571.h	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_82571.h	Sun Sep 13 18:26:05 2015	(r287762)
@@ -50,9 +50,10 @@
 #define E1000_EIAC_82574	0x000DC /* Ext. Interrupt Auto Clear - RW */
 #define E1000_EIAC_MASK_82574	0x01F00000
 
-#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */
+#define E1000_IVAR_INT_ALLOC_VALID	0x8
 
-#define E1000_RXCFGL    0x0B634 /* TimeSync Rx EtherType & Msg Type Reg - RW */
+/* Manageability Operation Mode mask */
+#define E1000_NVM_INIT_CTRL2_MNGM	0x6000
 
 #define E1000_BASE1000T_STATUS		10
 #define E1000_IDLE_ERROR_COUNT_MASK	0xFF

Modified: head/sys/dev/e1000/e1000_82575.c
==============================================================================
--- head/sys/dev/e1000/e1000_82575.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_82575.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -1235,7 +1235,7 @@ static s32 e1000_check_for_link_media_sw
 
 	DEBUGFUNC("e1000_check_for_link_media_swap");
 
-	/* Check the copper medium. */
+	/* Check for copper. */
 	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
 	if (ret_val)
 		return ret_val;
@@ -1247,7 +1247,7 @@ static s32 e1000_check_for_link_media_sw
 	if (data & E1000_M88E1112_STATUS_LINK)
 		port = E1000_MEDIA_PORT_COPPER;
 
-	/* Check the other medium. */
+	/* Check for other. */
 	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1);
 	if (ret_val)
 		return ret_val;
@@ -1256,11 +1256,6 @@ static s32 e1000_check_for_link_media_sw
 	if (ret_val)
 		return ret_val;
 
-	/* reset page to 0 */
-	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
-	if (ret_val)
-		return ret_val;
-
 	if (data & E1000_M88E1112_STATUS_LINK)
 		port = E1000_MEDIA_PORT_OTHER;
 
@@ -1268,8 +1263,20 @@ static s32 e1000_check_for_link_media_sw
 	if (port && (hw->dev_spec._82575.media_port != port)) {
 		hw->dev_spec._82575.media_port = port;
 		hw->dev_spec._82575.media_changed = TRUE;
+	}
+
+	if (port == E1000_MEDIA_PORT_COPPER) {
+		/* reset page to 0 */
+		ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
+		if (ret_val)
+			return ret_val;
+		e1000_check_for_link_82575(hw);
 	} else {
-		ret_val = e1000_check_for_link_82575(hw);
+		e1000_check_for_link_82575(hw);
+		/* reset page to 0 */
+		ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
+		if (ret_val)
+			return ret_val;
 	}
 
 	return E1000_SUCCESS;
@@ -2136,7 +2143,13 @@ void e1000_rx_fifo_flush_82575(struct e1
 	u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
 	int i, ms_wait;
 
-	DEBUGFUNC("e1000_rx_fifo_workaround_82575");
+	DEBUGFUNC("e1000_rx_fifo_flush_82575");
+
+	/* disable IPv6 options as per hardware errata */
+	rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+	rfctl |= E1000_RFCTL_IPV6_EX_DIS;
+	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
+
 	if (hw->mac.type != e1000_82575 ||
 	    !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
 		return;
@@ -2164,7 +2177,6 @@ void e1000_rx_fifo_flush_82575(struct e1
 	 * incoming packets are rejected.  Set enable and wait 2ms so that
 	 * any packet that was coming in as RCTL.EN was set is flushed
 	 */
-	rfctl = E1000_READ_REG(hw, E1000_RFCTL);
 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
 
 	rlpml = E1000_READ_REG(hw, E1000_RLPML);
@@ -2894,11 +2906,13 @@ out:
 /**
  *  e1000_set_eee_i350 - Enable/disable EEE support
  *  @hw: pointer to the HW structure
+ *  @adv1g: boolean flag enabling 1G EEE advertisement
+ *  @adv100m: boolean flag enabling 100M EEE advertisement
  *
  *  Enable/disable EEE based on setting in dev_spec structure.
  *
  **/
-s32 e1000_set_eee_i350(struct e1000_hw *hw)
+s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M)
 {
 	u32 ipcnfg, eeer;
 
@@ -2914,7 +2928,16 @@ s32 e1000_set_eee_i350(struct e1000_hw *
 	if (!(hw->dev_spec._82575.eee_disable)) {
 		u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
 
-		ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
+		if (adv100M)
+			ipcnfg |= E1000_IPCNFG_EEE_100M_AN;
+		else
+			ipcnfg &= ~E1000_IPCNFG_EEE_100M_AN;
+
+		if (adv1G)
+			ipcnfg |= E1000_IPCNFG_EEE_1G_AN;
+		else
+			ipcnfg &= ~E1000_IPCNFG_EEE_1G_AN;
+
 		eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
 			 E1000_EEER_LPI_FC);
 
@@ -2938,11 +2961,13 @@ out:
 /**
  *  e1000_set_eee_i354 - Enable/disable EEE support
  *  @hw: pointer to the HW structure
+ *  @adv1g: boolean flag enabling 1G EEE advertisement
+ *  @adv100m: boolean flag enabling 100M EEE advertisement
  *
  *  Enable/disable EEE legacy mode based on setting in dev_spec structure.
  *
  **/
-s32 e1000_set_eee_i354(struct e1000_hw *hw)
+s32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val = E1000_SUCCESS;
@@ -2984,8 +3009,16 @@ s32 e1000_set_eee_i354(struct e1000_hw *
 		if (ret_val)
 			goto out;
 
-		phy_data |= E1000_EEE_ADV_100_SUPPORTED |
-			    E1000_EEE_ADV_1000_SUPPORTED;
+		if (adv100M)
+			phy_data |= E1000_EEE_ADV_100_SUPPORTED;
+		else
+			phy_data &= ~E1000_EEE_ADV_100_SUPPORTED;
+
+		if (adv1G)
+			phy_data |= E1000_EEE_ADV_1000_SUPPORTED;
+		else
+			phy_data &= ~E1000_EEE_ADV_1000_SUPPORTED;
+
 		ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
 						E1000_EEE_ADV_DEV_I354,
 						phy_data);

Modified: head/sys/dev/e1000/e1000_82575.h
==============================================================================
--- head/sys/dev/e1000/e1000_82575.h	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_82575.h	Sun Sep 13 18:26:05 2015	(r287762)
@@ -495,8 +495,8 @@ void e1000_rlpml_set_vf(struct e1000_hw 
 s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type type);
 u16 e1000_rxpbs_adjust_82580(u32 data);
 s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data);
-s32 e1000_set_eee_i350(struct e1000_hw *);
-s32 e1000_set_eee_i354(struct e1000_hw *);
+s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M);
+s32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M);
 s32 e1000_get_eee_status_i354(struct e1000_hw *, bool *);
 s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw);
 

Modified: head/sys/dev/e1000/e1000_api.c
==============================================================================
--- head/sys/dev/e1000/e1000_api.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_api.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -299,6 +299,12 @@ s32 e1000_set_mac_type(struct e1000_hw *
 	case E1000_DEV_ID_PCH_I218_V3:
 		mac->type = e1000_pch_lpt;
 		break;
+	case E1000_DEV_ID_PCH_SPT_I219_LM:
+	case E1000_DEV_ID_PCH_SPT_I219_V:
+	case E1000_DEV_ID_PCH_SPT_I219_LM2:
+	case E1000_DEV_ID_PCH_SPT_I219_V2:
+		mac->type = e1000_pch_spt;
+		break;
 	case E1000_DEV_ID_82575EB_COPPER:
 	case E1000_DEV_ID_82575EB_FIBER_SERDES:
 	case E1000_DEV_ID_82575GB_QUAD_COPPER:
@@ -449,6 +455,7 @@ s32 e1000_setup_init_funcs(struct e1000_
 	case e1000_pchlan:
 	case e1000_pch2lan:
 	case e1000_pch_lpt:
+	case e1000_pch_spt:
 		e1000_init_function_pointers_ich8lan(hw);
 		break;
 	case e1000_82575:
@@ -929,21 +936,6 @@ s32 e1000_mng_enable_host_if(struct e100
 }
 
 /**
- *  e1000_set_obff_timer - Set Optimized Buffer Flush/Fill timer
- *  @hw: pointer to the HW structure
- *  @itr: u32 indicating itr value
- *
- *  Set the OBFF timer based on the given interrupt rate.
- **/
-s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr)
-{
-	if (hw->mac.ops.set_obff_timer)
-		return hw->mac.ops.set_obff_timer(hw, itr);
-
-	return E1000_SUCCESS;
-}
-
-/**
  *  e1000_check_reset_block - Verifies PHY can be reset
  *  @hw: pointer to the HW structure
  *
@@ -1216,6 +1208,21 @@ s32 e1000_read_pba_length(struct e1000_h
 }
 
 /**
+ *  e1000_read_pba_num - Read device part number
+ *  @hw: pointer to the HW structure
+ *  @pba_num: pointer to device part number
+ *
+ *  Reads the product board assembly (PBA) number from the EEPROM and stores
+ *  the value in pba_num.
+ *  Currently no func pointer exists and all implementations are handled in the
+ *  generic version of this function.
+ **/
+s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *pba_num)
+{
+	return e1000_read_pba_num_generic(hw, pba_num);
+}
+
+/**
  *  e1000_validate_nvm_checksum - Verifies NVM (EEPROM) checksum
  *  @hw: pointer to the HW structure
  *

Modified: head/sys/dev/e1000/e1000_api.h
==============================================================================
--- head/sys/dev/e1000/e1000_api.h	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_api.h	Sun Sep 13 18:26:05 2015	(r287762)
@@ -97,6 +97,7 @@ s32 e1000_phy_commit(struct e1000_hw *hw
 void e1000_power_up_phy(struct e1000_hw *hw);
 void e1000_power_down_phy(struct e1000_hw *hw);
 s32 e1000_read_mac_addr(struct e1000_hw *hw);
+s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *part_num);
 s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size);
 s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size);
 void e1000_reload_nvm(struct e1000_hw *hw);

Modified: head/sys/dev/e1000/e1000_defines.h
==============================================================================
--- head/sys/dev/e1000/e1000_defines.h	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_defines.h	Sun Sep 13 18:26:05 2015	(r287762)
@@ -197,6 +197,8 @@
 #define E1000_RCTL_LBM_TCVR	0x000000C0 /* tcvr loopback mode */
 #define E1000_RCTL_DTYP_PS	0x00000400 /* Packet Split descriptor */
 #define E1000_RCTL_RDMTS_HALF	0x00000000 /* Rx desc min thresh size */
+#define E1000_RCTL_RDMTS_HEX	0x00010000
+#define E1000_RCTL_RDMTS1_HEX	E1000_RCTL_RDMTS_HEX
 #define E1000_RCTL_MO_SHIFT	12 /* multicast offset shift */
 #define E1000_RCTL_MO_3		0x00003000 /* multicast offset 15:4 */
 #define E1000_RCTL_BAM		0x00008000 /* broadcast enable */
@@ -565,9 +567,6 @@
 #define E1000_ICR_THS		0x00800000 /* ICR.THS: Thermal Sensor Event*/
 #define E1000_ICR_MDDET		0x10000000 /* Malicious Driver Detect */
 
-#define E1000_ITR_MASK		0x000FFFFF /* ITR value bitfield */
-#define E1000_ITR_MULT		256 /* ITR mulitplier in nsec */
-
 /* PBA ECC Register */
 #define E1000_PBA_ECC_COUNTER_MASK	0xFFF00000 /* ECC counter mask */
 #define E1000_PBA_ECC_COUNTER_SHIFT	20 /* ECC counter shift value */
@@ -753,6 +752,12 @@
 #define E1000_TSYNCTXCTL_VALID		0x00000001 /* Tx timestamp valid */
 #define E1000_TSYNCTXCTL_ENABLED	0x00000010 /* enable Tx timestamping */
 
+/* HH Time Sync */
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK	0x0000F000 /* max delay */
+#define E1000_TSYNCTXCTL_SYNC_COMP_ERR		0x20000000 /* sync err */
+#define E1000_TSYNCTXCTL_SYNC_COMP		0x40000000 /* sync complete */
+#define E1000_TSYNCTXCTL_START_SYNC		0x80000000 /* initiate sync */
+
 #define E1000_TSYNCRXCTL_VALID		0x00000001 /* Rx timestamp valid */
 #define E1000_TSYNCRXCTL_TYPE_MASK	0x0000000E /* Rx type mask */
 #define E1000_TSYNCRXCTL_TYPE_L2_V2	0x00
@@ -1020,9 +1025,7 @@
 /* NVM Addressing bits based on type 0=small, 1=large */
 #define E1000_EECD_ADDR_BITS	0x00000400
 #define E1000_EECD_TYPE		0x00002000 /* NVM Type (1-SPI, 0-Microwire) */
-#ifndef E1000_NVM_GRANT_ATTEMPTS
 #define E1000_NVM_GRANT_ATTEMPTS	1000 /* NVM # attempts to gain grant */
-#endif
 #define E1000_EECD_AUTO_RD		0x00000200  /* NVM Auto Read done */
 #define E1000_EECD_SIZE_EX_MASK		0x00007800  /* NVM Size */
 #define E1000_EECD_SIZE_EX_SHIFT	11
@@ -1059,11 +1062,44 @@
 /* NVM Word Offsets */
 #define NVM_COMPAT			0x0003
 #define NVM_ID_LED_SETTINGS		0x0004
+#define NVM_VERSION			0x0005
 #define NVM_SERDES_AMPLITUDE		0x0006 /* SERDES output amplitude */
 #define NVM_PHY_CLASS_WORD		0x0007
 #define E1000_I210_NVM_FW_MODULE_PTR	0x0010
 #define E1000_I350_NVM_FW_MODULE_PTR	0x0051
 #define NVM_FUTURE_INIT_WORD1		0x0019
+#define NVM_ETRACK_WORD			0x0042
+#define NVM_ETRACK_HIWORD		0x0043
+#define NVM_COMB_VER_OFF		0x0083
+#define NVM_COMB_VER_PTR		0x003d
+
+/* NVM version defines */
+#define NVM_MAJOR_MASK			0xF000
+#define NVM_MINOR_MASK			0x0FF0
+#define NVM_IMAGE_ID_MASK		0x000F
+#define NVM_COMB_VER_MASK		0x00FF
+#define NVM_MAJOR_SHIFT			12
+#define NVM_MINOR_SHIFT			4
+#define NVM_COMB_VER_SHFT		8
+#define NVM_VER_INVALID			0xFFFF
+#define NVM_ETRACK_SHIFT		16
+#define NVM_ETRACK_VALID		0x8000
+#define NVM_NEW_DEC_MASK		0x0F00
+#define NVM_HEX_CONV			16
+#define NVM_HEX_TENS			10
+
+/* FW version defines */
+/* Offset of "Loader patch ptr" in Firmware Header */
+#define E1000_I350_NVM_FW_LOADER_PATCH_PTR_OFFSET	0x01
+/* Patch generation hour & minutes */
+#define E1000_I350_NVM_FW_VER_WORD1_OFFSET		0x04
+/* Patch generation month & day */
+#define E1000_I350_NVM_FW_VER_WORD2_OFFSET		0x05
+/* Patch generation year */
+#define E1000_I350_NVM_FW_VER_WORD3_OFFSET		0x06
+/* Patch major & minor numbers */
+#define E1000_I350_NVM_FW_VER_WORD4_OFFSET		0x07
+
 #define NVM_MAC_ADDR			0x0000
 #define NVM_SUB_DEV_ID			0x000B
 #define NVM_SUB_VEN_ID			0x000C
@@ -1440,8 +1476,6 @@
 #define I210_RXPBSIZE_DEFAULT		0x000000A2 /* RXPBSIZE default */
 #define I210_TXPBSIZE_DEFAULT		0x04000014 /* TXPBSIZE default */
 
-#define E1000_DOBFFCTL_OBFFTHR_MASK	0x000000FF /* OBFF threshold */
-#define E1000_DOBFFCTL_EXIT_ACT_MASK	0x01000000 /* Exit active CB */
 
 /* Proxy Filter Control */
 #define E1000_PROXYFC_D0		0x00000001 /* Enable offload in D0 */

Modified: head/sys/dev/e1000/e1000_hw.h
==============================================================================
--- head/sys/dev/e1000/e1000_hw.h	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_hw.h	Sun Sep 13 18:26:05 2015	(r287762)
@@ -137,6 +137,10 @@ struct e1000_hw;
 #define E1000_DEV_ID_PCH_I218_V2		0x15A1
 #define E1000_DEV_ID_PCH_I218_LM3		0x15A2 /* Wildcat Point PCH */
 #define E1000_DEV_ID_PCH_I218_V3		0x15A3 /* Wildcat Point PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_LM		0x156F /* Sunrise Point PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_V		0x1570 /* Sunrise Point PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_LM2		0x15B7 /* Sunrise Point-H PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_V2		0x15B8 /* Sunrise Point-H PCH */
 #define E1000_DEV_ID_82576			0x10C9
 #define E1000_DEV_ID_82576_FIBER		0x10E6
 #define E1000_DEV_ID_82576_SERDES		0x10E7
@@ -222,6 +226,7 @@ enum e1000_mac_type {
 	e1000_pchlan,
 	e1000_pch2lan,
 	e1000_pch_lpt,
+	e1000_pch_spt,
 	e1000_82575,
 	e1000_82576,
 	e1000_82580,
@@ -703,7 +708,6 @@ struct e1000_mac_operations {
 	int  (*rar_set)(struct e1000_hw *, u8*, u32);
 	s32  (*read_mac_addr)(struct e1000_hw *);
 	s32  (*validate_mdi_setting)(struct e1000_hw *);
-	s32  (*set_obff_timer)(struct e1000_hw *, u32);
 	s32  (*acquire_swfw_sync)(struct e1000_hw *, u16);
 	void (*release_swfw_sync)(struct e1000_hw *, u16);
 };
@@ -805,7 +809,7 @@ struct e1000_mac_info {
 	enum e1000_serdes_link_state serdes_link_state;
 	bool serdes_has_link;
 	bool tx_pkt_filtering;
-	u32 max_frame_size;
+	u32  max_frame_size;
 };
 
 struct e1000_phy_info {

Modified: head/sys/dev/e1000/e1000_i210.c
==============================================================================
--- head/sys/dev/e1000/e1000_i210.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_i210.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -489,6 +489,105 @@ static s32 e1000_read_invm_i210(struct e
 }
 
 /**
+ *  e1000_read_invm_version - Reads iNVM version and image type
+ *  @hw: pointer to the HW structure
+ *  @invm_ver: version structure for the version read
+ *
+ *  Reads iNVM version and image type.
+ **/
+s32 e1000_read_invm_version(struct e1000_hw *hw,
+			    struct e1000_fw_version *invm_ver)
+{
+	u32 *record = NULL;
+	u32 *next_record = NULL;
+	u32 i = 0;
+	u32 invm_dword = 0;
+	u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
+					     E1000_INVM_RECORD_SIZE_IN_BYTES);
+	u32 buffer[E1000_INVM_SIZE];
+	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
+	u16 version = 0;
+
+	DEBUGFUNC("e1000_read_invm_version");
+
+	/* Read iNVM memory */
+	for (i = 0; i < E1000_INVM_SIZE; i++) {
+		invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
+		buffer[i] = invm_dword;
+	}
+
+	/* Read version number */
+	for (i = 1; i < invm_blocks; i++) {
+		record = &buffer[invm_blocks - i];
+		next_record = &buffer[invm_blocks - i + 1];
+
+		/* Check if we have first version location used */
+		if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
+			version = 0;
+			status = E1000_SUCCESS;
+			break;
+		}
+		/* Check if we have second version location used */
+		else if ((i == 1) &&
+			 ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
+			version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
+			status = E1000_SUCCESS;
+			break;
+		}
+		/*
+		 * Check if we have odd version location
+		 * used and it is the last one used
+		 */
+		else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
+			 ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
+			 (i != 1))) {
+			version = (*next_record & E1000_INVM_VER_FIELD_TWO)
+				  >> 13;
+			status = E1000_SUCCESS;
+			break;
+		}
+		/*
+		 * Check if we have even version location
+		 * used and it is the last one used
+		 */
+		else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
+			 ((*record & 0x3) == 0)) {
+			version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
+			status = E1000_SUCCESS;
+			break;
+		}
+	}
+
+	if (status == E1000_SUCCESS) {
+		invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
+					>> E1000_INVM_MAJOR_SHIFT;
+		invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
+	}
+	/* Read Image Type */
+	for (i = 1; i < invm_blocks; i++) {
+		record = &buffer[invm_blocks - i];
+		next_record = &buffer[invm_blocks - i + 1];
+
+		/* Check if we have image type in first location used */
+		if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
+			invm_ver->invm_img_type = 0;
+			status = E1000_SUCCESS;
+			break;
+		}
+		/* Check if we have image type in first location used */
+		else if ((((*record & 0x3) == 0) &&
+			 ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
+			 ((((*record & 0x3) != 0) && (i != 1)))) {
+			invm_ver->invm_img_type =
+				(*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
+			status = E1000_SUCCESS;
+			break;
+		}
+	}
+	return status;
+}
+
+/**
  *  e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum
  *  @hw: pointer to the HW structure
  *

Modified: head/sys/dev/e1000/e1000_i210.h
==============================================================================
--- head/sys/dev/e1000/e1000_i210.h	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_i210.h	Sun Sep 13 18:26:05 2015	(r287762)
@@ -43,6 +43,8 @@ s32 e1000_write_nvm_srwr_i210(struct e10
 			      u16 words, u16 *data);
 s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
 			     u16 words, u16 *data);
+s32 e1000_read_invm_version(struct e1000_hw *hw,
+			    struct e1000_fw_version *invm_ver);
 s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
 void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
 s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,

Modified: head/sys/dev/e1000/e1000_ich8lan.c
==============================================================================
--- head/sys/dev/e1000/e1000_ich8lan.c	Sun Sep 13 17:17:52 2015	(r287761)
+++ head/sys/dev/e1000/e1000_ich8lan.c	Sun Sep 13 18:26:05 2015	(r287762)
@@ -92,10 +92,13 @@ static s32  e1000_set_d3_lplu_state_ich8
 					    bool active);
 static s32  e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset,
 				   u16 words, u16 *data);
+static s32  e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words,
+			       u16 *data);
 static s32  e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset,
 				    u16 words, u16 *data);
 static s32  e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw);
 static s32  e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw);
+static s32  e1000_update_nvm_checksum_spt(struct e1000_hw *hw);
 static s32  e1000_valid_led_default_ich8lan(struct e1000_hw *hw,
 					    u16 *data);
 static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
@@ -123,6 +126,14 @@ static s32  e1000_read_flash_byte_ich8la
 					  u32 offset, u8 *data);
 static s32  e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 					  u8 size, u16 *data);
+static s32  e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
+					    u32 *data);
+static s32  e1000_read_flash_dword_ich8lan(struct e1000_hw *hw,
+					   u32 offset, u32 *data);
+static s32  e1000_write_flash_data32_ich8lan(struct e1000_hw *hw,
+					     u32 offset, u32 data);
+static s32  e1000_retry_write_flash_dword_ich8lan(struct e1000_hw *hw,
+						  u32 offset, u32 dword);
 static s32  e1000_read_flash_word_ich8lan(struct e1000_hw *hw,
 					  u32 offset, u16 *data);
 static s32  e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
@@ -133,7 +144,6 @@ static s32 e1000_check_for_copper_link_i
 static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
 static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
 static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
-static s32 e1000_set_obff_timer_pch_lpt(struct e1000_hw *hw, u32 itr);
 
 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
 /* Offset 04h HSFSTS */
@@ -232,16 +242,21 @@ static bool e1000_phy_is_accessible_pchl
 	if (ret_val)
 		return FALSE;
 out:
-	if (hw->mac.type == e1000_pch_lpt) {
-		/* Unforce SMBus mode in PHY */
-		hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg);
-		phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
-		hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, phy_reg);
+	if ((hw->mac.type == e1000_pch_lpt) ||
+	    (hw->mac.type == e1000_pch_spt)) {
+		/* Only unforce SMBus if ME is not active */
+		if (!(E1000_READ_REG(hw, E1000_FWSM) &
+		    E1000_ICH_FWSM_FW_VALID)) {
+			/* Unforce SMBus mode in PHY */
+			hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg);
+			phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
+			hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, phy_reg);
 
-		/* Unforce SMBus mode in MAC */
-		mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
-		mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
-		E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg);
+			/* Unforce SMBus mode in MAC */
+			mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
+			mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
+			E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg);
+		}
 	}
 
 	return TRUE;
@@ -328,6 +343,7 @@ static s32 e1000_init_phy_workarounds_pc
 	 */
 	switch (hw->mac.type) {
 	case e1000_pch_lpt:
+	case e1000_pch_spt:
 		if (e1000_phy_is_accessible_pchlan(hw))
 			break;
 
@@ -475,6 +491,7 @@ static s32 e1000_init_phy_params_pchlan(
 			/* fall-through */
 		case e1000_pch2lan:
 		case e1000_pch_lpt:
+		case e1000_pch_spt:
 			/* In case the PHY needs to be in mdio slow mode,
 			 * set slow mode and try to get the PHY id again.
 			 */
@@ -617,36 +634,53 @@ static s32 e1000_init_nvm_params_ich8lan
 	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
 	u32 gfpreg, sector_base_addr, sector_end_addr;
 	u16 i;
+	u32 nvm_size;
 
 	DEBUGFUNC("e1000_init_nvm_params_ich8lan");
 
 	/* Can't read flash registers if the register set isn't mapped. */
 	nvm->type = e1000_nvm_flash_sw;
-	if (!hw->flash_address) {
-		DEBUGOUT("ERROR: Flash registers not mapped\n");
-		return -E1000_ERR_CONFIG;
-	}
+	/* in SPT, gfpreg doesn't exist. NVM size is taken from the
+	 * STRAP register
+	 */
+	if (hw->mac.type == e1000_pch_spt) {
+		nvm->flash_base_addr = 0;
+		nvm_size =
+		    (((E1000_READ_REG(hw, E1000_STRAP) >> 1) & 0x1F) + 1)
+		    * NVM_SIZE_MULTIPLIER;
+		nvm->flash_bank_size = nvm_size / 2;
+		/* Adjust to word count */
+		nvm->flash_bank_size /= sizeof(u16);
+		/* Set the base address for flash register access */
+		hw->flash_address = hw->hw_addr + E1000_FLASH_BASE_ADDR;
+	} else {
+		if (!hw->flash_address) {
+			DEBUGOUT("ERROR: Flash registers not mapped\n");
+			return -E1000_ERR_CONFIG;
+		}
+
+		gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
+
+		/* sector_X_addr is a "sector"-aligned address (4096 bytes)
+		 * Add 1 to sector_end_addr since this sector is included in
+		 * the overall size.
+		 */
+		sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
+		sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
 
-	gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
+		/* flash_base_addr is byte-aligned */
+		nvm->flash_base_addr = sector_base_addr
+				       << FLASH_SECTOR_ADDR_SHIFT;
 
-	/* sector_X_addr is a "sector"-aligned address (4096 bytes)
-	 * Add 1 to sector_end_addr since this sector is included in
-	 * the overall size.
-	 */
-	sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
-	sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
-
-	/* flash_base_addr is byte-aligned */
-	nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;
-
-	/* find total size of the NVM, then cut in half since the total
-	 * size represents two separate NVM banks.
-	 */
-	nvm->flash_bank_size = ((sector_end_addr - sector_base_addr)
-				<< FLASH_SECTOR_ADDR_SHIFT);
-	nvm->flash_bank_size /= 2;
-	/* Adjust to word count */
-	nvm->flash_bank_size /= sizeof(u16);
+		/* find total size of the NVM, then cut in half since the total
+		 * size represents two separate NVM banks.
+		 */
+		nvm->flash_bank_size = ((sector_end_addr - sector_base_addr)
+					<< FLASH_SECTOR_ADDR_SHIFT);
+		nvm->flash_bank_size /= 2;
+		/* Adjust to word count */
+		nvm->flash_bank_size /= sizeof(u16);
+	}
 
 	nvm->word_size = E1000_SHADOW_RAM_WORDS;
 
@@ -662,8 +696,13 @@ static s32 e1000_init_nvm_params_ich8lan
 	/* Function Pointers */
 	nvm->ops.acquire	= e1000_acquire_nvm_ich8lan;
 	nvm->ops.release	= e1000_release_nvm_ich8lan;
-	nvm->ops.read		= e1000_read_nvm_ich8lan;
-	nvm->ops.update		= e1000_update_nvm_checksum_ich8lan;
+	if (hw->mac.type == e1000_pch_spt) {
+		nvm->ops.read	= e1000_read_nvm_spt;
+		nvm->ops.update	= e1000_update_nvm_checksum_spt;
+	} else {
+		nvm->ops.read	= e1000_read_nvm_ich8lan;
+		nvm->ops.update	= e1000_update_nvm_checksum_ich8lan;
+	}
 	nvm->ops.valid_led_default = e1000_valid_led_default_ich8lan;
 	nvm->ops.validate	= e1000_validate_nvm_checksum_ich8lan;
 	nvm->ops.write		= e1000_write_nvm_ich8lan;
@@ -681,9 +720,7 @@ static s32 e1000_init_nvm_params_ich8lan
 static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
-#if defined(QV_RELEASE) || !defined(NO_PCH_LPT_B0_SUPPORT)
 	u16 pci_cfg;
-#endif /* QV_RELEASE || !defined(NO_PCH_LPT_B0_SUPPORT) */
 
 	DEBUGFUNC("e1000_init_mac_params_ich8lan");
 
@@ -752,15 +789,21 @@ static s32 e1000_init_mac_params_ich8lan
 		mac->ops.rar_set = e1000_rar_set_pch2lan;
 		/* fall-through */
 	case e1000_pch_lpt:
+	case e1000_pch_spt:
 		/* multicast address update for pch2 */
 		mac->ops.update_mc_addr_list =
 			e1000_update_mc_addr_list_pch2lan;
+		/* fall-through */
 	case e1000_pchlan:
-#if defined(QV_RELEASE) || !defined(NO_PCH_LPT_B0_SUPPORT)
 		/* save PCH revision_id */
 		e1000_read_pci_cfg(hw, E1000_PCI_REVISION_ID_REG, &pci_cfg);
-		hw->revision_id = (u8)(pci_cfg &= 0x000F);
-#endif /* QV_RELEASE || !defined(NO_PCH_LPT_B0_SUPPORT) */
+		/* SPT uses full byte for revision ID,
+		 * as opposed to previous generations
+		 */
+		if (hw->mac.type >= e1000_pch_spt)
+			hw->revision_id = (u8)(pci_cfg &= 0x00FF);
+		else
+			hw->revision_id = (u8)(pci_cfg &= 0x000F);
 		/* check management mode */
 		mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
 		/* ID LED init */
@@ -777,11 +820,11 @@ static s32 e1000_init_mac_params_ich8lan
 		break;
 	}
 
-	if (mac->type == e1000_pch_lpt) {
+	if ((mac->type == e1000_pch_lpt) ||
+	    (mac->type == e1000_pch_spt)) {
 		mac->rar_entry_count = E1000_PCH_LPT_RAR_ENTRIES;
 		mac->ops.rar_set = e1000_rar_set_pch_lpt;
 		mac->ops.setup_physical_interface = e1000_setup_copper_link_pch_lpt;
-		mac->ops.set_obff_timer = e1000_set_obff_timer_pch_lpt;
 	}
 
 	/* Enable PCS Lock-loss workaround for ICH8 */
@@ -1007,8 +1050,9 @@ release:
 		/* clear FEXTNVM6 bit 8 on link down or 10/100 */
 		fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK;
 
-		if (!link || ((status & E1000_STATUS_SPEED_100) &&
-			      (status & E1000_STATUS_FD)))
+		if ((hw->phy.revision > 5) || !link ||
+		    ((status & E1000_STATUS_SPEED_100) &&
+		     (status & E1000_STATUS_FD)))
 			goto update_fextnvm6;
 
 		ret_val = hw->phy.ops.read_reg(hw, I217_INBAND_CTRL, &reg);
@@ -1044,168 +1088,6 @@ update_fextnvm6:
 	return ret_val;
 }
 
-static u64 e1000_ltr2ns(u16 ltr)
-{
-	u32 value, scale;
-
-	/* Determine the latency in nsec based on the LTR value & scale */
-	value = ltr & E1000_LTRV_VALUE_MASK;
-	scale = (ltr & E1000_LTRV_SCALE_MASK) >> E1000_LTRV_SCALE_SHIFT;
-
-	return value * (1 << (scale * E1000_LTRV_SCALE_FACTOR));
-}
-
-/**
- *  e1000_platform_pm_pch_lpt - Set platform power management values
- *  @hw: pointer to the HW structure
- *  @link: bool indicating link status
- *
- *  Set the Latency Tolerance Reporting (LTR) values for the "PCIe-like"
- *  GbE MAC in the Lynx Point PCH based on Rx buffer size and link speed
- *  when link is up (which must not exceed the maximum latency supported
- *  by the platform), otherwise specify there is no LTR requirement.
- *  Unlike TRUE-PCIe devices which set the LTR maximum snoop/no-snoop
- *  latencies in the LTR Extended Capability Structure in the PCIe Extended
- *  Capability register set, on this device LTR is set by writing the
- *  equivalent snoop/no-snoop latencies in the LTRV register in the MAC and
- *  set the SEND bit to send an Intel On-chip System Fabric sideband (IOSF-SB)
- *  message to the PMC.
- *
- *  Use the LTR value to calculate the Optimized Buffer Flush/Fill (OBFF)
- *  high-water mark.
- **/
-static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
-{
-	u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) |
-		  link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND;
-	u16 lat_enc = 0;	/* latency encoded */
-	s32 obff_hwm = 0;
-
-	DEBUGFUNC("e1000_platform_pm_pch_lpt");
-
-	if (link) {
-		u16 speed, duplex, scale = 0;
-		u16 max_snoop, max_nosnoop;
-		u16 max_ltr_enc;	/* max LTR latency encoded */
-		s64 lat_ns;
-		s64 value;
-		u32 rxa;
-
-		if (!hw->mac.max_frame_size) {
-			DEBUGOUT("max_frame_size not set.\n");
-			return -E1000_ERR_CONFIG;
-		}
-
-		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
-		if (!speed) {
-			DEBUGOUT("Speed not set.\n");
-			return -E1000_ERR_CONFIG;
-		}
-
-		/* Rx Packet Buffer Allocation size (KB) */
-		rxa = E1000_READ_REG(hw, E1000_PBA) & E1000_PBA_RXA_MASK;
-
-		/* Determine the maximum latency tolerated by the device.
-		 *
-		 * Per the PCIe spec, the tolerated latencies are encoded as
-		 * a 3-bit encoded scale (only 0-5 are valid) multiplied by
-		 * a 10-bit value (0-1023) to provide a range from 1 ns to
-		 * 2^25*(2^10-1) ns.  The scale is encoded as 0=2^0ns,
-		 * 1=2^5ns, 2=2^10ns,...5=2^25ns.
-		 */
-		lat_ns = ((s64)rxa * 1024 -
-			  (2 * (s64)hw->mac.max_frame_size)) * 8 * 1000;
-		if (lat_ns < 0)
-			lat_ns = 0;
-		else
-			lat_ns /= speed;
-		value = lat_ns;
-
-		while (value > E1000_LTRV_VALUE_MASK) {
-			scale++;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list