[Midnightbsd-cvs] src [9506] trunk/sys/dev: sync Intel nic driver (em/igb) with FreeBSD 9 stable august 14, 2017

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Tue Aug 15 06:40:50 EDT 2017


Revision: 9506
          http://svnweb.midnightbsd.org/src/?rev=9506
Author:   laffer1
Date:     2017-08-15 06:40:50 -0400 (Tue, 15 Aug 2017)
Log Message:
-----------
sync Intel nic driver (em/igb) with FreeBSD 9 stable august 14, 2017

Modified Paths:
--------------
    trunk/sys/dev/e1000/LICENSE
    trunk/sys/dev/e1000/README
    trunk/sys/dev/e1000/e1000_80003es2lan.c
    trunk/sys/dev/e1000/e1000_80003es2lan.h
    trunk/sys/dev/e1000/e1000_82540.c
    trunk/sys/dev/e1000/e1000_82541.c
    trunk/sys/dev/e1000/e1000_82541.h
    trunk/sys/dev/e1000/e1000_82542.c
    trunk/sys/dev/e1000/e1000_82543.c
    trunk/sys/dev/e1000/e1000_82543.h
    trunk/sys/dev/e1000/e1000_82571.c
    trunk/sys/dev/e1000/e1000_82571.h
    trunk/sys/dev/e1000/e1000_82575.c
    trunk/sys/dev/e1000/e1000_82575.h
    trunk/sys/dev/e1000/e1000_api.c
    trunk/sys/dev/e1000/e1000_api.h
    trunk/sys/dev/e1000/e1000_defines.h
    trunk/sys/dev/e1000/e1000_hw.h
    trunk/sys/dev/e1000/e1000_i210.c
    trunk/sys/dev/e1000/e1000_i210.h
    trunk/sys/dev/e1000/e1000_ich8lan.c
    trunk/sys/dev/e1000/e1000_ich8lan.h
    trunk/sys/dev/e1000/e1000_mac.c
    trunk/sys/dev/e1000/e1000_mac.h
    trunk/sys/dev/e1000/e1000_manage.c
    trunk/sys/dev/e1000/e1000_manage.h
    trunk/sys/dev/e1000/e1000_mbx.c
    trunk/sys/dev/e1000/e1000_mbx.h
    trunk/sys/dev/e1000/e1000_nvm.c
    trunk/sys/dev/e1000/e1000_nvm.h
    trunk/sys/dev/e1000/e1000_osdep.c
    trunk/sys/dev/e1000/e1000_osdep.h
    trunk/sys/dev/e1000/e1000_phy.c
    trunk/sys/dev/e1000/e1000_phy.h
    trunk/sys/dev/e1000/e1000_regs.h
    trunk/sys/dev/e1000/e1000_vf.c
    trunk/sys/dev/e1000/e1000_vf.h
    trunk/sys/dev/e1000/if_em.c
    trunk/sys/dev/e1000/if_em.h
    trunk/sys/dev/e1000/if_igb.c
    trunk/sys/dev/e1000/if_igb.h
    trunk/sys/dev/e1000/if_lem.c
    trunk/sys/dev/e1000/if_lem.h
    trunk/sys/dev/pci/pcireg.h

Modified: trunk/sys/dev/e1000/LICENSE
===================================================================
--- trunk/sys/dev/e1000/LICENSE	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/LICENSE	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,4 @@
-$FreeBSD: release/9.2.0/sys/dev/e1000/LICENSE 203049 2010-01-26 22:32:22Z jfv $
+$FreeBSD: stable/9/sys/dev/e1000/LICENSE 203049 2010-01-26 22:32:22Z jfv $
 
   Copyright (c) 2001-2010, Intel Corporation 
   All rights reserved.

Modified: trunk/sys/dev/e1000/README
===================================================================
--- trunk/sys/dev/e1000/README	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/README	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,4 @@
-$FreeBSD: release/9.2.0/sys/dev/e1000/README 252899 2013-07-06 22:34:42Z jfv $
+$FreeBSD: stable/9/sys/dev/e1000/README 252899 2013-07-06 22:34:42Z jfv $
 FreeBSD* Driver for Intel Network Connection
 =============================================
 

Modified: trunk/sys/dev/e1000/e1000_80003es2lan.c
===================================================================
--- trunk/sys/dev/e1000/e1000_80003es2lan.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_80003es2lan.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,18 +30,14 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_80003es2lan.c 235527 2012-05-16 22:22:52Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_80003es2lan.c 269647 2014-08-06 22:15:01Z jfv $*/
 
-/*
- * 80003ES2LAN Gigabit Ethernet Controller (Copper)
+/* 80003ES2LAN Gigabit Ethernet Controller (Copper)
  * 80003ES2LAN Gigabit Ethernet Controller (Serdes)
  */
 
 #include "e1000_api.h"
 
-static s32  e1000_init_phy_params_80003es2lan(struct e1000_hw *hw);
-static s32  e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw);
-static s32  e1000_init_mac_params_80003es2lan(struct e1000_hw *hw);
 static s32  e1000_acquire_phy_80003es2lan(struct e1000_hw *hw);
 static void e1000_release_phy_80003es2lan(struct e1000_hw *hw);
 static s32  e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw);
@@ -72,14 +67,12 @@
 					    u16 *data);
 static s32  e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
 					     u16 data);
-static s32  e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw);
 static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw);
 static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
 static s32  e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw);
 static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw);
 
-/*
- * A table for the GG82563 cable length where the range is defined
+/* A table for the GG82563 cable length where the range is defined
  * with a lower bound at "index" and the upper bound at
  * "index + 5".
  */
@@ -96,13 +89,13 @@
 static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	DEBUGFUNC("e1000_init_phy_params_80003es2lan");
 
 	if (hw->phy.media_type != e1000_media_type_copper) {
 		phy->type = e1000_phy_none;
-		goto out;
+		return E1000_SUCCESS;
 	} else {
 		phy->ops.power_up = e1000_power_up_phy_copper;
 		phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan;
@@ -134,12 +127,9 @@
 	ret_val = e1000_get_phy_id(hw);
 
 	/* Verify phy id */
-	if (phy->id != GG82563_E_PHY_ID) {
-		ret_val = -E1000_ERR_PHY;
-		goto out;
-	}
+	if (phy->id != GG82563_E_PHY_ID)
+		return -E1000_ERR_PHY;
 
-out:
 	return ret_val;
 }
 
@@ -177,8 +167,7 @@
 	size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
 		     E1000_EECD_SIZE_EX_SHIFT);
 
-	/*
-	 * Added to a constant, "size" becomes the left-shift value
+	/* Added to a constant, "size" becomes the left-shift value
 	 * for setting word_size.
 	 */
 	size += NVM_WORD_SIZE_BASE_SHIFT;
@@ -235,8 +224,8 @@
 	/* FWSM register */
 	mac->has_fwsm = TRUE;
 	/* ARC supported; valid only if manageability features are enabled. */
-	mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) &
-				    E1000_FWSM_MODE_MASK) ? TRUE : FALSE;
+	mac->arc_subsystem_valid = !!(E1000_READ_REG(hw, E1000_FWSM) &
+				      E1000_FWSM_MODE_MASK);
 	/* Adaptive IFS not supported */
 	mac->adaptive_ifs = FALSE;
 
@@ -378,7 +367,7 @@
 
 	ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	ret_val = e1000_acquire_nvm_generic(hw);
 
@@ -385,7 +374,6 @@
 	if (ret_val)
 		e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
 
-out:
 	return ret_val;
 }
 
@@ -416,23 +404,20 @@
 	u32 swfw_sync;
 	u32 swmask = mask;
 	u32 fwmask = mask << 16;
-	s32 ret_val = E1000_SUCCESS;
-	s32 i = 0, timeout = 50;
+	s32 i = 0;
+	s32 timeout = 50;
 
 	DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan");
 
 	while (i < timeout) {
-		if (e1000_get_hw_semaphore_generic(hw)) {
-			ret_val = -E1000_ERR_SWFW_SYNC;
-			goto out;
-		}
+		if (e1000_get_hw_semaphore_generic(hw))
+			return -E1000_ERR_SWFW_SYNC;
 
 		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
 		if (!(swfw_sync & (fwmask | swmask)))
 			break;
 
-		/*
-		 * Firmware currently using resource (fwmask)
+		/* Firmware currently using resource (fwmask)
 		 * or other software thread using resource (swmask)
 		 */
 		e1000_put_hw_semaphore_generic(hw);
@@ -442,8 +427,7 @@
 
 	if (i == timeout) {
 		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
-		ret_val = -E1000_ERR_SWFW_SYNC;
-		goto out;
+		return -E1000_ERR_SWFW_SYNC;
 	}
 
 	swfw_sync |= swmask;
@@ -451,8 +435,7 @@
 
 	e1000_put_hw_semaphore_generic(hw);
 
-out:
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -498,14 +481,13 @@
 
 	ret_val = e1000_acquire_phy_80003es2lan(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* Select Configuration Page */
 	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
 		page_select = GG82563_PHY_PAGE_SELECT;
 	} else {
-		/*
-		 * Use Alternative Page Select register to access
+		/* Use Alternative Page Select register to access
 		 * registers 30 and 31
 		 */
 		page_select = GG82563_PHY_PAGE_SELECT_ALT;
@@ -515,12 +497,11 @@
 	ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp);
 	if (ret_val) {
 		e1000_release_phy_80003es2lan(hw);
-		goto out;
+		return ret_val;
 	}
 
-	if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) {
-		/*
-		 * The "ready" bit in the MDIC register may be incorrectly set
+	if (hw->dev_spec._80003es2lan.mdic_wa_enable) {
+		/* The "ready" bit in the MDIC register may be incorrectly set
 		 * before the device has completed the "Page Select" MDI
 		 * transaction.  So we wait 200us after each MDI command...
 		 */
@@ -530,9 +511,8 @@
 		ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
 
 		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
-			ret_val = -E1000_ERR_PHY;
 			e1000_release_phy_80003es2lan(hw);
-			goto out;
+			return -E1000_ERR_PHY;
 		}
 
 		usec_delay(200);
@@ -550,7 +530,6 @@
 
 	e1000_release_phy_80003es2lan(hw);
 
-out:
 	return ret_val;
 }
 
@@ -573,14 +552,13 @@
 
 	ret_val = e1000_acquire_phy_80003es2lan(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* Select Configuration Page */
 	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
 		page_select = GG82563_PHY_PAGE_SELECT;
 	} else {
-		/*
-		 * Use Alternative Page Select register to access
+		/* Use Alternative Page Select register to access
 		 * registers 30 and 31
 		 */
 		page_select = GG82563_PHY_PAGE_SELECT_ALT;
@@ -590,12 +568,11 @@
 	ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp);
 	if (ret_val) {
 		e1000_release_phy_80003es2lan(hw);
-		goto out;
+		return ret_val;
 	}
 
-	if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) {
-		/*
-		 * The "ready" bit in the MDIC register may be incorrectly set
+	if (hw->dev_spec._80003es2lan.mdic_wa_enable) {
+		/* The "ready" bit in the MDIC register may be incorrectly set
 		 * before the device has completed the "Page Select" MDI
 		 * transaction.  So we wait 200us after each MDI command...
 		 */
@@ -605,9 +582,8 @@
 		ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
 
 		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
-			ret_val = -E1000_ERR_PHY;
 			e1000_release_phy_80003es2lan(hw);
-			goto out;
+			return -E1000_ERR_PHY;
 		}
 
 		usec_delay(200);
@@ -625,7 +601,6 @@
 
 	e1000_release_phy_80003es2lan(hw);
 
-out:
 	return ret_val;
 }
 
@@ -656,7 +631,6 @@
 static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw)
 {
 	s32 timeout = PHY_CFG_TIMEOUT;
-	s32 ret_val = E1000_SUCCESS;
 	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
 
 	DEBUGFUNC("e1000_get_cfg_done_80003es2lan");
@@ -672,12 +646,10 @@
 	}
 	if (!timeout) {
 		DEBUGOUT("MNG configuration cycle has not completed.\n");
-		ret_val = -E1000_ERR_RESET;
-		goto out;
+		return -E1000_ERR_RESET;
 	}
 
-out:
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -689,7 +661,7 @@
  **/
 static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u16 phy_data;
 	bool link;
 
@@ -696,26 +668,25 @@
 	DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan");
 
 	if (!(hw->phy.ops.read_reg))
-		goto out;
+		return E1000_SUCCESS;
 
-	/*
-	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
+	/* Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
 	 * forced whenever speed and duplex are forced.
 	 */
 	ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO;
 	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	DEBUGOUT1("GG82563 PSCR: %X\n", phy_data);
 
 	ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	e1000_phy_force_speed_duplex_setup(hw, &phy_data);
 
@@ -724,7 +695,7 @@
 
 	ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	usec_delay(1);
 
@@ -734,16 +705,15 @@
 		ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
 						     100000, &link);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		if (!link) {
-			/*
-			 * We didn't get link.
+			/* We didn't get link.
 			 * Reset the DSP and cross our fingers.
 			 */
 			ret_val = e1000_phy_reset_dsp_generic(hw);
 			if (ret_val)
-				goto out;
+				return ret_val;
 		}
 
 		/* Try once more */
@@ -750,16 +720,15 @@
 		ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
 						     100000, &link);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
 	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
 				       &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
-	/*
-	 * Resetting the phy means we need to verify the TX_CLK corresponds
+	/* Resetting the phy means we need to verify the TX_CLK corresponds
 	 * to the link speed.  10Mbps -> 2.5MHz, else 25MHz.
 	 */
 	phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
@@ -768,8 +737,7 @@
 	else
 		phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25;
 
-	/*
-	 * In addition, we must re-enable CRS on Tx for both half and full
+	/* In addition, we must re-enable CRS on Tx for both half and full
 	 * duplex.
 	 */
 	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
@@ -776,7 +744,6 @@
 	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
 					phy_data);
 
-out:
 	return ret_val;
 }
 
@@ -790,24 +757,22 @@
 static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u16 phy_data, index;
 
 	DEBUGFUNC("e1000_get_cable_length_80003es2lan");
 
 	if (!(hw->phy.ops.read_reg))
-		goto out;
+		return E1000_SUCCESS;
 
 	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	index = phy_data & GG82563_DSPD_CABLE_LENGTH;
 
-	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) {
-		ret_val = -E1000_ERR_PHY;
-		goto out;
-	}
+	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5)
+		return -E1000_ERR_PHY;
 
 	phy->min_cable_length = e1000_gg82563_cable_length_table[index];
 	phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5];
@@ -814,8 +779,7 @@
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
-out:
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -856,11 +820,11 @@
 {
 	u32 ctrl;
 	s32 ret_val;
+	u16 kum_reg_data;
 
 	DEBUGFUNC("e1000_reset_hw_80003es2lan");
 
-	/*
-	 * Prevent the PCI-E bus from sticking if there is no TLP connection
+	/* Prevent the PCI-E bus from sticking if there is no TLP connection
 	 * on the last TLP read/write transaction when MAC is reset.
 	 */
 	ret_val = e1000_disable_pcie_master_generic(hw);
@@ -879,23 +843,30 @@
 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
 
 	ret_val = e1000_acquire_phy_80003es2lan(hw);
+	if (ret_val)
+		return ret_val;
+
 	DEBUGOUT("Issuing a global reset to MAC\n");
 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
 	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_get_auto_rd_done_generic(hw);
 	if (ret_val)
 		/* We don't want to continue accessing MAC registers. */
-		goto out;
+		return ret_val;
 
 	/* Clear any pending interrupt events. */
 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
 	E1000_READ_REG(hw, E1000_ICR);
 
-	ret_val = e1000_check_alt_mac_addr_generic(hw);
-
-out:
-	return ret_val;
+	return e1000_check_alt_mac_addr_generic(hw);
 }
 
 /**
@@ -918,9 +889,9 @@
 
 	/* Initialize identification LED */
 	ret_val = mac->ops.id_led_init(hw);
+	/* An error is not fatal and we should not stop init due to this */
 	if (ret_val)
 		DEBUGOUT("Error initializing identification LED\n");
-		/* This is not fatal and we should not stop init due to this */
 
 	/* Disabling VLAN filtering */
 	DEBUGOUT("Initializing the IEEE VLAN\n");
@@ -936,6 +907,8 @@
 
 	/* Setup link and flow control */
 	ret_val = mac->ops.setup_link(hw);
+	if (ret_val)
+		return ret_val;
 
 	/* Disable IBIST slave mode (far-end loopback) */
 	e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
@@ -946,14 +919,14 @@
 
 	/* Set the transmit descriptor write-back policy */
 	reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0));
-	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
-		   E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;
+	reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) |
+		    E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC);
 	E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data);
 
 	/* ...for both queues. */
 	reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1));
-	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
-		   E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;
+	reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) |
+		    E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC);
 	E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data);
 
 	/* Enable retransmit on late collisions */
@@ -980,10 +953,9 @@
 	/* default to TRUE to enable the MDIC W/A */
 	hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE;
 
-	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
-						 E1000_KMRNCTRLSTA_OFFSET >>
-						 E1000_KMRNCTRLSTA_OFFSET_SHIFT,
-						 &i);
+	ret_val =
+	    e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET >>
+					    E1000_KMRNCTRLSTA_OFFSET_SHIFT, &i);
 	if (!ret_val) {
 		if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) ==
 		     E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO)
@@ -990,8 +962,7 @@
 			hw->dev_spec._80003es2lan.mdic_wa_enable = FALSE;
 	}
 
-	/*
-	 * Clear all of the statistics registers (clear on read).  It is
+	/* Clear all of the statistics registers (clear on read).  It is
 	 * important that we do this after we have tried to establish link
 	 * because the symbol error count will increment wildly if there
 	 * is no link.
@@ -1038,6 +1009,13 @@
 		reg |= (1 << 28);
 	E1000_WRITE_REG(hw, E1000_TARC(1), reg);
 
+	/* Disable IPv6 extension header parsing because some malformed
+	 * IPv6 headers can hang the Rx.
+	 */
+	reg = E1000_READ_REG(hw, E1000_RFCTL);
+	reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);
+	E1000_WRITE_REG(hw, E1000_RFCTL, reg);
+
 	return;
 }
 
@@ -1051,7 +1029,7 @@
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
-	u32 ctrl_ext;
+	u32 reg;
 	u16 data;
 
 	DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan");
@@ -1058,7 +1036,7 @@
 
 	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
 	/* Use 25MHz for both link down and 1000Base-T for Tx clock. */
@@ -1066,10 +1044,9 @@
 
 	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
-	/*
-	 * Options:
+	/* Options:
 	 *   MDI/MDI-X = 0 (default)
 	 *   0 - Auto for all speeds
 	 *   1 - MDI mode
@@ -1078,7 +1055,7 @@
 	 */
 	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
 
@@ -1095,8 +1072,7 @@
 		break;
 	}
 
-	/*
-	 * Options:
+	/* Options:
 	 *   disable_polarity_correction = 0 (default)
 	 *       Automatic Correction for Reversed Cable Polarity
 	 *   0 - Disabled
@@ -1108,90 +1084,86 @@
 
 	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* SW Reset the PHY so all changes take effect */
 	ret_val = hw->phy.ops.commit(hw);
 	if (ret_val) {
 		DEBUGOUT("Error Resetting the PHY\n");
-		goto out;
+		return ret_val;
 	}
 
 	/* Bypass Rx and Tx FIFO's */
-	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
-					E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
-					E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
-					E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);
+	reg = E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL;
+	data = (E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
+		E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, reg, data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
-	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
-				E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, &data);
+	reg = E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE;
+	ret_val = e1000_read_kmrn_reg_80003es2lan(hw, reg, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 	data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;
-	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
-				E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, data);
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, reg, data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
 	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL_2, data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
-	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
-	ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);
-	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
+	reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
+	reg &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
+	E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
 
 	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
-	/*
-	 * Do not init these registers when the HW is in IAMT mode, since the
+	/* Do not init these registers when the HW is in IAMT mode, since the
 	 * firmware will have already initialized them.  We only initialize
 	 * them if the HW is not in IAMT mode.
 	 */
-	if (!(hw->mac.ops.check_mng_mode(hw))) {
+	if (!hw->mac.ops.check_mng_mode(hw)) {
 		/* Enable Electrical Idle on the PHY */
 		data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
 		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
 						data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 					       &data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
 		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 						data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
-	/*
-	 * Workaround: Disable padding in Kumeran interface in the MAC
+	/* Workaround: Disable padding in Kumeran interface in the MAC
 	 * and in the PHY to avoid CRC errors.
 	 */
 	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_INBAND_CTRL, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	data |= GG82563_ICR_DIS_PADDING;
 	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_INBAND_CTRL, data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
-out:
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -1214,8 +1186,7 @@
 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
 
-	/*
-	 * Set the mac to wait the maximum time between each
+	/* Set the mac to wait the maximum time between each
 	 * iteration and increase the max iterations when
 	 * polling the phy; this fixes erroneous timeouts at 10Mbps.
 	 */
@@ -1222,34 +1193,35 @@
 	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4),
 						   0xFFFF);
 	if (ret_val)
-		goto out;
+		return ret_val;
 	ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
 						  &reg_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 	reg_data |= 0x3F;
 	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
 						   reg_data);
 	if (ret_val)
-		goto out;
-	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
-				E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, &reg_data);
+		return ret_val;
+	ret_val =
+	    e1000_read_kmrn_reg_80003es2lan(hw,
+					    E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
+					    &reg_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 	reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING;
-	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
-				E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, reg_data);
+	ret_val =
+	    e1000_write_kmrn_reg_80003es2lan(hw,
+					     E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
+					     reg_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
-	ret_val = e1000_setup_copper_link_generic(hw);
-
-out:
-	return ret_val;
+	return e1000_setup_copper_link_generic(hw);
 }
 
 /**
@@ -1272,7 +1244,7 @@
 		ret_val = e1000_get_speed_and_duplex_copper_generic(hw, &speed,
 								    &duplex);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		if (speed == SPEED_1000)
 			ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);
@@ -1280,7 +1252,6 @@
 			ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex);
 	}
 
-out:
 	return ret_val;
 }
 
@@ -1294,7 +1265,7 @@
  **/
 static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u32 tipg;
 	u32 i = 0;
 	u16 reg_data, reg_data2;
@@ -1302,11 +1273,12 @@
 	DEBUGFUNC("e1000_configure_kmrn_for_10_100");
 
 	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT;
-	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
-				       E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
-				       reg_data);
+	ret_val =
+	    e1000_write_kmrn_reg_80003es2lan(hw,
+					     E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
+					     reg_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* Configure Transmit Inter-Packet Gap */
 	tipg = E1000_READ_REG(hw, E1000_TIPG);
@@ -1318,12 +1290,12 @@
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 					       &reg_data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 					       &reg_data2);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		i++;
 	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
 
@@ -1332,11 +1304,7 @@
 	else
 		reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
 
-	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
-					reg_data);
-
-out:
-	return ret_val;
+	return hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
 }
 
 /**
@@ -1348,7 +1316,7 @@
  **/
 static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u16 reg_data, reg_data2;
 	u32 tipg;
 	u32 i = 0;
@@ -1356,10 +1324,12 @@
 	DEBUGFUNC("e1000_configure_kmrn_for_1000");
 
 	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;
-	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
-				E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, reg_data);
+	ret_val =
+	    e1000_write_kmrn_reg_80003es2lan(hw,
+					     E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
+					     reg_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* Configure Transmit Inter-Packet Gap */
 	tipg = E1000_READ_REG(hw, E1000_TIPG);
@@ -1371,21 +1341,18 @@
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 					       &reg_data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 					       &reg_data2);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		i++;
 	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
 
 	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
-	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
-					reg_data);
 
-out:
-	return ret_val;
+	return hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
 }
 
 /**
@@ -1402,13 +1369,13 @@
 					   u16 *data)
 {
 	u32 kmrnctrlsta;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan");
 
 	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
 		       E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
@@ -1422,7 +1389,6 @@
 
 	e1000_release_mac_csr_80003es2lan(hw);
 
-out:
 	return ret_val;
 }
 
@@ -1440,13 +1406,13 @@
 					    u16 data)
 {
 	u32 kmrnctrlsta;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan");
 
 	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
 		       E1000_KMRNCTRLSTA_OFFSET) | data;
@@ -1457,7 +1423,6 @@
 
 	e1000_release_mac_csr_80003es2lan(hw);
 
-out:
 	return ret_val;
 }
 
@@ -1467,23 +1432,19 @@
  **/
 static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	DEBUGFUNC("e1000_read_mac_addr_80003es2lan");
 
-	/*
-	 * If there's an alternate MAC address place it in RAR0
+	/* If there's an alternate MAC address place it in RAR0
 	 * so that it will override the Si installed default perm
 	 * address.
 	 */
 	ret_val = e1000_check_alt_mac_addr_generic(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
-	ret_val = e1000_read_mac_addr_generic(hw);
-
-out:
-	return ret_val;
+	return e1000_read_mac_addr_generic(hw);
 }
 
 /**

Modified: trunk/sys/dev/e1000/e1000_80003es2lan.h
===================================================================
--- trunk/sys/dev/e1000/e1000_80003es2lan.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_80003es2lan.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_80003es2lan.h 235527 2012-05-16 22:22:52Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_80003es2lan.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_80003ES2LAN_H_
 #define _E1000_80003ES2LAN_H_
@@ -52,7 +51,7 @@
 #define E1000_KMRNCTRLSTA_OPMODE_MASK		0x000C
 #define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO	0x0004
 
-#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
+#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gig Carry Extend Padding */
 #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN	0x00010000
 
 #define DEFAULT_TIPG_IPGT_1000_80003ES2LAN	0x8
@@ -59,7 +58,7 @@
 #define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN	0x9
 
 /* GG82563 PHY Specific Status Register (Page 0, Register 16 */
-#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE	0x0002 /* 1=Reversal Disabled */
+#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE	0x0002 /* 1=Reversal Dis */
 #define GG82563_PSCR_CROSSOVER_MODE_MASK	0x0060
 #define GG82563_PSCR_CROSSOVER_MODE_MDI		0x0000 /* 00=Manual MDI */
 #define GG82563_PSCR_CROSSOVER_MODE_MDIX	0x0020 /* 01=Manual MDIX */
@@ -66,7 +65,7 @@
 #define GG82563_PSCR_CROSSOVER_MODE_AUTO	0x0060 /* 11=Auto crossover */
 
 /* PHY Specific Control Register 2 (Page 0, Register 26) */
-#define GG82563_PSCR2_REVERSE_AUTO_NEG		0x2000 /* 1=Reverse Auto-Nego */
+#define GG82563_PSCR2_REVERSE_AUTO_NEG		0x2000 /* 1=Reverse Auto-Neg */
 
 /* MAC Specific Control Register (Page 2, Register 21) */
 /* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
@@ -73,13 +72,11 @@
 #define GG82563_MSCR_TX_CLK_MASK		0x0007
 #define GG82563_MSCR_TX_CLK_10MBPS_2_5		0x0004
 #define GG82563_MSCR_TX_CLK_100MBPS_25		0x0005
-#define GG82563_MSCR_TX_CLK_1000MBPS_2_5	0x0006
 #define GG82563_MSCR_TX_CLK_1000MBPS_25		0x0007
 
 #define GG82563_MSCR_ASSERT_CRS_ON_TX		0x0010 /* 1=Assert */
 
-/* DSP Distance Register (Page 5, Register 26) */
-/*
+/* DSP Distance Register (Page 5, Register 26)
  * 0 = <50M
  * 1 = 50-80M
  * 2 = 80-100M

Modified: trunk/sys/dev/e1000/e1000_82540.c
===================================================================
--- trunk/sys/dev/e1000/e1000_82540.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82540.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2011, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82540.c 235527 2012-05-16 22:22:52Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82540.c 235527 2012-05-16 22:22:52Z jfv $*/
 
 /*
  * 82540EM Gigabit Ethernet Controller

Modified: trunk/sys/dev/e1000/e1000_82541.c
===================================================================
--- trunk/sys/dev/e1000/e1000_82541.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82541.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2011, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82541.c 238262 2012-07-08 20:35:56Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82541.c 238262 2012-07-08 20:35:56Z jfv $*/
 
 /*
  * 82541EI Gigabit Ethernet Controller

Modified: trunk/sys/dev/e1000/e1000_82541.h
===================================================================
--- trunk/sys/dev/e1000/e1000_82541.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82541.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2008, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82541.h 181027 2008-07-30 21:56:53Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82541.h 181027 2008-07-30 21:56:53Z jfv $*/
 
 #ifndef _E1000_82541_H_
 #define _E1000_82541_H_

Modified: trunk/sys/dev/e1000/e1000_82542.c
===================================================================
--- trunk/sys/dev/e1000/e1000_82542.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82542.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2010, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82542.c 218581 2011-02-11 17:18:42Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82542.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 /*
  * 82542 Gigabit Ethernet Controller
@@ -48,7 +47,7 @@
 static s32  e1000_setup_link_82542(struct e1000_hw *hw);
 static s32  e1000_led_on_82542(struct e1000_hw *hw);
 static s32  e1000_led_off_82542(struct e1000_hw *hw);
-static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index);
+static int  e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index);
 static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw);
 static s32  e1000_read_mac_addr_82542(struct e1000_hw *hw);
 
@@ -410,7 +409,7 @@
  *  Sets the receive address array register at index to the address passed
  *  in by addr.
  **/
-static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index)
+static int e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index)
 {
 	u32 rar_low, rar_high;
 
@@ -432,6 +431,7 @@
 
 	E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
 	E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
+	return E1000_SUCCESS;
 }
 
 /**

Modified: trunk/sys/dev/e1000/e1000_82543.c
===================================================================
--- trunk/sys/dev/e1000/e1000_82543.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82543.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2011, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82543.c 238262 2012-07-08 20:35:56Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82543.c 238262 2012-07-08 20:35:56Z jfv $*/
 
 /*
  * 82543GC Gigabit Ethernet Controller (Fiber)

Modified: trunk/sys/dev/e1000/e1000_82543.h
===================================================================
--- trunk/sys/dev/e1000/e1000_82543.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82543.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2008, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82543.h 181027 2008-07-30 21:56:53Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82543.h 181027 2008-07-30 21:56:53Z jfv $*/
 
 #ifndef _E1000_82543_H_
 #define _E1000_82543_H_

Modified: trunk/sys/dev/e1000/e1000_82571.c
===================================================================
--- trunk/sys/dev/e1000/e1000_82571.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82571.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82571.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82571.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 /* 82571EB Gigabit Ethernet Controller
  * 82571EB Gigabit Ethernet Controller (Copper)
@@ -928,9 +927,9 @@
 	}
 
 	for (i = 0; i < words; i++) {
-		eewr = (data[i] << E1000_NVM_RW_REG_DATA) |
-		       ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
-		       E1000_NVM_RW_REG_START;
+		eewr = ((data[i] << E1000_NVM_RW_REG_DATA) |
+			((offset + i) << E1000_NVM_RW_ADDR_SHIFT) |
+			E1000_NVM_RW_REG_START);
 
 		ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE);
 		if (ret_val)
@@ -1102,8 +1101,6 @@
 	default:
 		break;
 	}
-	if (ret_val)
-		DEBUGOUT("Cannot acquire MDIO ownership\n");
 
 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
 
@@ -1112,9 +1109,16 @@
 
 	/* Must release MDIO ownership and mutex after MAC reset. */
 	switch (hw->mac.type) {
+	case e1000_82573:
+		/* Release mutex only if the hw semaphore is acquired */
+		if (!ret_val)
+			e1000_put_hw_semaphore_82573(hw);
+		break;
 	case e1000_82574:
 	case e1000_82583:
-		e1000_put_hw_semaphore_82574(hw);
+		/* Release mutex only if the hw semaphore is acquired */
+		if (!ret_val)
+			e1000_put_hw_semaphore_82574(hw);
 		break;
 	default:
 		break;
@@ -1223,8 +1227,8 @@
 
 	/* Set the transmit descriptor write-back policy */
 	reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0));
-	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
-		   E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;
+	reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) |
+		    E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC);
 	E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data);
 
 	/* ...for both queues. */
@@ -1240,9 +1244,9 @@
 		break;
 	default:
 		reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1));
-		reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
-			   E1000_TXDCTL_FULL_TX_DESC_WB |
-			   E1000_TXDCTL_COUNT_DESC;
+		reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) |
+			    E1000_TXDCTL_FULL_TX_DESC_WB |
+			    E1000_TXDCTL_COUNT_DESC);
 		E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data);
 		break;
 	}
@@ -1449,10 +1453,14 @@
 static bool e1000_check_mng_mode_82574(struct e1000_hw *hw)
 {
 	u16 data;
+	s32 ret_val;
 
 	DEBUGFUNC("e1000_check_mng_mode_82574");
 
-	hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+	ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+	if (ret_val)
+		return FALSE;
+
 	return (data & E1000_NVM_INIT_CTRL2_MNGM) != 0;
 }
 

Modified: trunk/sys/dev/e1000/e1000_82571.h
===================================================================
--- trunk/sys/dev/e1000/e1000_82571.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82571.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2010, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,34 +30,35 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82571.h 213234 2010-09-28 00:13:15Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82571.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_82571_H_
 #define _E1000_82571_H_
 
-#define ID_LED_RESERVED_F746 0xF746
-#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
-                              (ID_LED_OFF1_ON2  <<  8) | \
-                              (ID_LED_DEF1_DEF2 <<  4) | \
-                              (ID_LED_DEF1_DEF2))
+#define ID_LED_RESERVED_F746	0xF746
+#define ID_LED_DEFAULT_82573	((ID_LED_DEF1_DEF2 << 12) | \
+				 (ID_LED_OFF1_ON2  <<  8) | \
+				 (ID_LED_DEF1_DEF2 <<  4) | \
+				 (ID_LED_DEF1_DEF2))
 
-#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
-#define AN_RETRY_COUNT          5 /* Autoneg Retry Count value */
+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX	0x08000000
+#define AN_RETRY_COUNT		5 /* Autoneg Retry Count value */
 
 /* Intr Throttling - RW */
-#define E1000_EITR_82574(_n)    (0x000E8 + (0x4 * (_n)))
+#define E1000_EITR_82574(_n)	(0x000E8 + (0x4 * (_n)))
 
-#define E1000_EIAC_82574        0x000DC /* Ext. Interrupt Auto Clear - RW */
-#define E1000_EIAC_MASK_82574   0x01F00000
+#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
-#define E1000_RECEIVE_ERROR_COUNTER 21
-#define E1000_RECEIVE_ERROR_MAX 0xFFFF
+#define E1000_BASE1000T_STATUS		10
+#define E1000_IDLE_ERROR_COUNT_MASK	0xFF
+#define E1000_RECEIVE_ERROR_COUNTER	21
+#define E1000_RECEIVE_ERROR_MAX		0xFFFF
 bool e1000_check_phy_82574(struct e1000_hw *hw);
 bool e1000_get_laa_state_82571(struct e1000_hw *hw);
 void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state);

Modified: trunk/sys/dev/e1000/e1000_82575.c
===================================================================
--- trunk/sys/dev/e1000/e1000_82575.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82575.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82575.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82575.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 /*
  * 82575EB Gigabit Network Connection
@@ -53,10 +52,10 @@
 static s32  e1000_acquire_nvm_82575(struct e1000_hw *hw);
 static void e1000_release_nvm_82575(struct e1000_hw *hw);
 static s32  e1000_check_for_link_82575(struct e1000_hw *hw);
+static s32  e1000_check_for_link_media_swap(struct e1000_hw *hw);
 static s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
 static s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
 					 u16 *duplex);
-static s32  e1000_init_hw_82575(struct e1000_hw *hw);
 static s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
 static s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
 					   u16 *data);
@@ -120,7 +119,8 @@
 static const u16 e1000_82580_rxpbs_table[] = {
 	36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
 #define E1000_82580_RXPBS_TABLE_SIZE \
-	(sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
+	(sizeof(e1000_82580_rxpbs_table) / \
+	 sizeof(e1000_82580_rxpbs_table[0]))
 
 
 /**
@@ -145,6 +145,7 @@
 		break;
 	case e1000_82580:
 	case e1000_i350:
+	case e1000_i354:
 	case e1000_i210:
 	case e1000_i211:
 		reg = E1000_READ_REG(hw, E1000_MDICNFG);
@@ -208,6 +209,7 @@
 		switch (hw->mac.type) {
 		case e1000_82580:
 		case e1000_i350:
+		case e1000_i354:
 			phy->ops.read_reg = e1000_read_phy_reg_82580;
 			phy->ops.write_reg = e1000_write_phy_reg_82580;
 			break;
@@ -227,6 +229,8 @@
 
 	/* Verify phy id and set remaining function pointers */
 	switch (phy->id) {
+	case M88E1543_E_PHY_ID:
+	case M88E1512_E_PHY_ID:
 	case I347AT4_E_PHY_ID:
 	case M88E1112_E_PHY_ID:
 	case M88E1340M_E_PHY_ID:
@@ -239,9 +243,41 @@
 		    phy->id == M88E1340M_E_PHY_ID)
 			phy->ops.get_cable_length =
 					 e1000_get_cable_length_m88_gen2;
+		else if (phy->id == M88E1543_E_PHY_ID ||
+			 phy->id == M88E1512_E_PHY_ID)
+			phy->ops.get_cable_length =
+					 e1000_get_cable_length_m88_gen2;
 		else
 			phy->ops.get_cable_length = e1000_get_cable_length_m88;
 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
+		/* Check if this PHY is confgured for media swap. */
+		if (phy->id == M88E1112_E_PHY_ID) {
+			u16 data;
+
+			ret_val = phy->ops.write_reg(hw,
+						     E1000_M88E1112_PAGE_ADDR,
+						     2);
+			if (ret_val)
+				goto out;
+
+			ret_val = phy->ops.read_reg(hw,
+						    E1000_M88E1112_MAC_CTRL_1,
+						    &data);
+			if (ret_val)
+				goto out;
+
+			data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >>
+			       E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT;
+			if (data == E1000_M88E1112_AUTO_COPPER_SGMII ||
+			    data == E1000_M88E1112_AUTO_COPPER_BASEX)
+				hw->mac.ops.check_for_link =
+						e1000_check_for_link_media_swap;
+		}
+		if (phy->id == M88E1512_E_PHY_ID) {
+			ret_val = e1000_initialize_M88E1512_phy(hw);
+			if (ret_val)
+				goto out;
+		}
 		break;
 	case IGP03E1000_E_PHY_ID:
 	case IGP04E1000_E_PHY_ID:
@@ -356,6 +392,7 @@
 		nvm->ops.update = e1000_update_nvm_checksum_82580;
 		break;
 	case e1000_i350:
+	case e1000_i354:
 		nvm->ops.validate = e1000_validate_nvm_checksum_i350;
 		nvm->ops.update = e1000_update_nvm_checksum_i350;
 		break;
@@ -389,7 +426,7 @@
 		mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
 	if (mac->type == e1000_82580)
 		mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
-	if (mac->type == e1000_i350)
+	if (mac->type == e1000_i350 || mac->type == e1000_i354)
 		mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
 
 	/* Enable EEE default settings for EEE supported devices */
@@ -418,6 +455,9 @@
 	else
 	mac->ops.reset_hw = e1000_reset_hw_82575;
 	/* hw initialization */
+	if ((mac->type == e1000_i210) || (mac->type == e1000_i211))
+		mac->ops.init_hw = e1000_init_hw_i210;
+	else
 	mac->ops.init_hw = e1000_init_hw_82575;
 	/* link setup */
 	mac->ops.setup_link = e1000_setup_link_generic;
@@ -437,7 +477,7 @@
 	mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
 	/* multicast address update */
 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
-	if (mac->type == e1000_i350) {
+	if (hw->mac.type == e1000_i350 || mac->type == e1000_i354) {
 		/* writing VFTA */
 		mac->ops.write_vfta = e1000_write_vfta_i350;
 		/* clearing VFTA */
@@ -623,6 +663,10 @@
 
 	DEBUGFUNC("e1000_get_phy_id_82575");
 
+	/* some i354 devices need an extra read for phy id */
+	if (hw->mac.type == e1000_i354)
+		e1000_get_phy_id(hw);
+
 	/*
 	 * For SGMII PHYs, we try the list of possible addresses until
 	 * we find one that works.  For non-SGMII PHYs
@@ -646,6 +690,7 @@
 			break;
 		case e1000_82580:
 		case e1000_i350:
+		case e1000_i354:
 		case e1000_i210:
 		case e1000_i211:
 			mdic = E1000_READ_REG(hw, E1000_MDICNFG);
@@ -713,6 +758,7 @@
 static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
 {
 	s32 ret_val = E1000_SUCCESS;
+	struct e1000_phy_info *phy = &hw->phy;
 
 	DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
 
@@ -735,7 +781,11 @@
 		goto out;
 
 	ret_val = hw->phy.ops.commit(hw);
+	if (ret_val)
+		goto out;
 
+	if (phy->id == M88E1512_E_PHY_ID)
+		ret_val = e1000_initialize_M88E1512_phy(hw);
 out:
 	return ret_val;
 }
@@ -842,7 +892,6 @@
 static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val = E1000_SUCCESS;
 	u32 data;
 
 	DEBUGFUNC("e1000_set_d0_lplu_state_82580");
@@ -870,7 +919,7 @@
 	}
 
 	E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -890,7 +939,6 @@
 s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val = E1000_SUCCESS;
 	u32 data;
 
 	DEBUGFUNC("e1000_set_d3_lplu_state_82580");
@@ -918,7 +966,7 @@
 	}
 
 	E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -932,7 +980,7 @@
  **/
 static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
 {
-	s32 ret_val;
+	s32 ret_val = E1000_SUCCESS;
 
 	DEBUGFUNC("e1000_acquire_nvm_82575");
 
@@ -954,6 +1002,7 @@
 			DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
 		}
 	}
+
 	if (hw->mac.type == e1000_82580) {
 		u32 eecd = E1000_READ_REG(hw, E1000_EECD);
 		if (eecd & E1000_EECD_BLOCKED) {
@@ -964,7 +1013,6 @@
 		}
 	}
 
-
 	ret_val = e1000_acquire_nvm_generic(hw);
 	if (ret_val)
 		e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
@@ -1078,7 +1126,6 @@
 static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
 {
 	s32 timeout = PHY_CFG_TIMEOUT;
-	s32 ret_val = E1000_SUCCESS;
 	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
 
 	DEBUGFUNC("e1000_get_cfg_done_82575");
@@ -1103,7 +1150,7 @@
 	    (hw->phy.type == e1000_phy_igp_3))
 		e1000_phy_init_script_igp3(hw);
 
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -1174,6 +1221,61 @@
 }
 
 /**
+ *  e1000_check_for_link_media_swap - Check which M88E1112 interface linked
+ *  @hw: pointer to the HW structure
+ *
+ *  Poll the M88E1112 interfaces to see which interface achieved link.
+ */
+static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 data;
+	u8 port = 0;
+
+	DEBUGFUNC("e1000_check_for_link_media_swap");
+
+	/* Check the copper medium. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
+	if (ret_val)
+		return ret_val;
+
+	ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
+	if (ret_val)
+		return ret_val;
+
+	if (data & E1000_M88E1112_STATUS_LINK)
+		port = E1000_MEDIA_PORT_COPPER;
+
+	/* Check the other medium. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1);
+	if (ret_val)
+		return ret_val;
+
+	ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
+	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;
+
+	/* Determine if a swap needs to happen. */
+	if (port && (hw->dev_spec._82575.media_port != port)) {
+		hw->dev_spec._82575.media_port = port;
+		hw->dev_spec._82575.media_changed = TRUE;
+	} else {
+		ret_val = e1000_check_for_link_82575(hw);
+	}
+
+	return E1000_SUCCESS;
+}
+
+/**
  *  e1000_power_up_serdes_link_82575 - Power up the serdes link after shutdown
  *  @hw: pointer to the HW structure
  **/
@@ -1216,6 +1318,7 @@
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	u32 pcs;
+	u32 status;
 
 	DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
 
@@ -1246,6 +1349,18 @@
 		else
 			*duplex = HALF_DUPLEX;
 
+		/* Check if it is an I354 2.5Gb backplane connection. */
+		if (mac->type == e1000_i354) {
+			status = E1000_READ_REG(hw, E1000_STATUS);
+			if ((status & E1000_STATUS_2P5_SKU) &&
+			    !(status & E1000_STATUS_2P5_SKU_OVER)) {
+				*speed = SPEED_2500;
+				*duplex = FULL_DUPLEX;
+				DEBUGOUT("2500 Mbs, ");
+				DEBUGOUT("Full Duplex\n");
+			}
+		}
+
 	} else {
 		mac->serdes_has_link = FALSE;
 		*speed = 0;
@@ -1361,7 +1476,7 @@
  *
  *  This inits the hardware readying it for operation.
  **/
-static s32 e1000_init_hw_82575(struct e1000_hw *hw)
+s32 e1000_init_hw_82575(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	s32 ret_val;
@@ -1431,11 +1546,18 @@
 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
 
-	/* Clear Go Link Disconnect bit */
-	if (hw->mac.type >= e1000_82580) {
+	/* Clear Go Link Disconnect bit on supported devices */
+	switch (hw->mac.type) {
+	case e1000_82580:
+	case e1000_i350:
+	case e1000_i210:
+	case e1000_i211:
 		phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
 		phpm_reg &= ~E1000_82580_PM_GO_LINKD;
 		E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
+		break;
+	default:
+		break;
 	}
 
 	ret_val = e1000_setup_serdes_link_82575(hw);
@@ -1459,6 +1581,8 @@
 		case I347AT4_E_PHY_ID:
 		case M88E1112_E_PHY_ID:
 		case M88E1340M_E_PHY_ID:
+		case M88E1543_E_PHY_ID:
+		case M88E1512_E_PHY_ID:
 		case I210_I_PHY_ID:
 			ret_val = e1000_copper_link_setup_m88_gen2(hw);
 			break;
@@ -1871,7 +1995,7 @@
  **/
 static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	DEBUGFUNC("e1000_read_mac_addr_82575");
 
@@ -2133,42 +2257,33 @@
  **/
 void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
 {
-	u32 dtxswc;
+	u32 reg_val, reg_offset;
 
 	switch (hw->mac.type) {
 	case e1000_82576:
-		dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
-		if (enable) {
-			dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
-				   E1000_DTXSWC_VLAN_SPOOF_MASK);
-			/* The PF can spoof - it has to in order to
-			 * support emulation mode NICs */
-			dtxswc ^= (1 << pf | 1 << (pf +
-				   E1000_DTXSWC_VLAN_SPOOF_SHIFT));
-		} else {
-			dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
-				    E1000_DTXSWC_VLAN_SPOOF_MASK);
-		}
-		E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
+		reg_offset = E1000_DTXSWC;
 		break;
 	case e1000_i350:
-		dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
-		if (enable) {
-			dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
-				   E1000_DTXSWC_VLAN_SPOOF_MASK);
-			/* The PF can spoof - it has to in order to
-			 * support emulation mode NICs
-			 */
-			dtxswc ^= (1 << pf | 1 << (pf +
-				   E1000_DTXSWC_VLAN_SPOOF_SHIFT));
-		} else {
-			dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
-				    E1000_DTXSWC_VLAN_SPOOF_MASK);
-		}
-		E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc);
+	case e1000_i354:
+		reg_offset = E1000_TXSWC;
+		break;
 	default:
-		break;
+		return;
 	}
+
+	reg_val = E1000_READ_REG(hw, reg_offset);
+	if (enable) {
+		reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
+			     E1000_DTXSWC_VLAN_SPOOF_MASK);
+		/* The PF can spoof - it has to in order to
+		 * support emulation mode NICs
+		 */
+		reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
+	} else {
+		reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
+			     E1000_DTXSWC_VLAN_SPOOF_MASK);
+	}
+	E1000_WRITE_REG(hw, reg_offset, reg_val);
 }
 
 /**
@@ -2192,6 +2307,7 @@
 		E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
 		break;
 	case e1000_i350:
+	case e1000_i354:
 		dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
 		if (enable)
 			dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
@@ -2283,7 +2399,7 @@
  *  e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits
  *  @hw: pointer to the HW structure
  *
- *  This resets the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on
+ *  This resets the the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on
  *  the values found in the EEPROM.  This addresses an issue in which these
  *  bits are not restored from EEPROM after reset.
  **/
@@ -2372,12 +2488,18 @@
 		ctrl |= E1000_CTRL_RST;
 
 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-	E1000_WRITE_FLUSH(hw);
 
-	/* Add delay to insure DEV_RST has time to complete */
-	if (global_device_reset)
-		msec_delay(5);
+	switch (hw->device_id) {
+	case E1000_DEV_ID_DH89XXCC_SGMII:
+		break;
+	default:
+		E1000_WRITE_FLUSH(hw);
+		break;
+	}
 
+	/* Add delay to insure DEV_RST or RST has time to complete */
+	msec_delay(5);
+
 	ret_val = e1000_get_auto_rd_done_generic(hw);
 	if (ret_val) {
 		/*
@@ -2388,10 +2510,6 @@
 		DEBUGOUT("Auto Read Done did not complete\n");
 	}
 
-	/* If EEPROM is not present, run manual init scripts */
-	if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
-		e1000_reset_init_script_82575(hw);
-
 	/* clear global device reset status bit */
 	E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET);
 
@@ -2515,7 +2633,7 @@
  **/
 static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u16 eeprom_regions_count = 1;
 	u16 j, nvm_data;
 	u16 nvm_offset;
@@ -2646,6 +2764,134 @@
 }
 
 /**
+ *  __e1000_access_emi_reg - Read/write EMI register
+ *  @hw: pointer to the HW structure
+ *  @addr: EMI address to program
+ *  @data: pointer to value to read/write from/to the EMI address
+ *  @read: boolean flag to indicate read or write
+ **/
+static s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 address,
+				  u16 *data, bool read)
+{
+	s32 ret_val;
+
+	DEBUGFUNC("__e1000_access_emi_reg");
+
+	ret_val = hw->phy.ops.write_reg(hw, E1000_EMIADD, address);
+	if (ret_val)
+		return ret_val;
+
+	if (read)
+		ret_val = hw->phy.ops.read_reg(hw, E1000_EMIDATA, data);
+	else
+		ret_val = hw->phy.ops.write_reg(hw, E1000_EMIDATA, *data);
+
+	return ret_val;
+}
+
+/**
+ *  e1000_read_emi_reg - Read Extended Management Interface register
+ *  @hw: pointer to the HW structure
+ *  @addr: EMI address to program
+ *  @data: value to be read from the EMI address
+ **/
+s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
+{
+	DEBUGFUNC("e1000_read_emi_reg");
+
+	return __e1000_access_emi_reg(hw, addr, data, TRUE);
+}
+
+/**
+ *  e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Initialize Marverl 1512 to work correctly with Avoton.
+ **/
+s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val = E1000_SUCCESS;
+
+	DEBUGFUNC("e1000_initialize_M88E1512_phy");
+
+	/* Check if this is correct PHY. */
+	if (phy->id != M88E1512_E_PHY_ID)
+		goto out;
+
+	/* Switch to PHY page 0xFF. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
+	if (ret_val)
+		goto out;
+
+	/* Switch to PHY page 0xFB. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D);
+	if (ret_val)
+		goto out;
+
+	/* Switch to PHY page 0x12. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
+	if (ret_val)
+		goto out;
+
+	/* Change mode to SGMII-to-Copper */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
+	if (ret_val)
+		goto out;
+
+	/* Return the PHY to page 0. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.commit(hw);
+	if (ret_val) {
+		DEBUGOUT("Error committing the PHY changes\n");
+		return ret_val;
+	}
+
+	msec_delay(1000);
+out:
+	return ret_val;
+}
+
+/**
  *  e1000_set_eee_i350 - Enable/disable EEE support
  *  @hw: pointer to the HW structure
  *
@@ -2654,7 +2900,6 @@
  **/
 s32 e1000_set_eee_i350(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
 	u32 ipcnfg, eeer;
 
 	DEBUGFUNC("e1000_set_eee_i350");
@@ -2687,9 +2932,117 @@
 	E1000_READ_REG(hw, E1000_EEER);
 out:
 
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_set_eee_i354 - Enable/disable EEE support
+ *  @hw: pointer to the HW structure
+ *
+ *  Enable/disable EEE legacy mode based on setting in dev_spec structure.
+ *
+ **/
+s32 e1000_set_eee_i354(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val = E1000_SUCCESS;
+	u16 phy_data;
+
+	DEBUGFUNC("e1000_set_eee_i354");
+
+	if ((hw->phy.media_type != e1000_media_type_copper) ||
+	    ((phy->id != M88E1543_E_PHY_ID) &&
+	    (phy->id != M88E1512_E_PHY_ID)))
+		goto out;
+
+	if (!hw->dev_spec._82575.eee_disable) {
+		/* Switch to PHY page 18. */
+		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18);
+		if (ret_val)
+			goto out;
+
+		ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1,
+					    &phy_data);
+		if (ret_val)
+			goto out;
+
+		phy_data |= E1000_M88E1543_EEE_CTRL_1_MS;
+		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1,
+					     phy_data);
+		if (ret_val)
+			goto out;
+
+		/* Return the PHY to page 0. */
+		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
+		if (ret_val)
+			goto out;
+
+		/* Turn on EEE advertisement. */
+		ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
+					       E1000_EEE_ADV_DEV_I354,
+					       &phy_data);
+		if (ret_val)
+			goto out;
+
+		phy_data |= E1000_EEE_ADV_100_SUPPORTED |
+			    E1000_EEE_ADV_1000_SUPPORTED;
+		ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
+						E1000_EEE_ADV_DEV_I354,
+						phy_data);
+	} else {
+		/* Turn off EEE advertisement. */
+		ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
+					       E1000_EEE_ADV_DEV_I354,
+					       &phy_data);
+		if (ret_val)
+			goto out;
+
+		phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED |
+			      E1000_EEE_ADV_1000_SUPPORTED);
+		ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
+						E1000_EEE_ADV_DEV_I354,
+						phy_data);
+	}
+
+out:
 	return ret_val;
 }
 
+/**
+ *  e1000_get_eee_status_i354 - Get EEE status
+ *  @hw: pointer to the HW structure
+ *  @status: EEE status
+ *
+ *  Get EEE status by guessing based on whether Tx or Rx LPI indications have
+ *  been received.
+ **/
+s32 e1000_get_eee_status_i354(struct e1000_hw *hw, bool *status)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val = E1000_SUCCESS;
+	u16 phy_data;
+
+	DEBUGFUNC("e1000_get_eee_status_i354");
+
+	/* Check if EEE is supported on this device. */
+	if ((hw->phy.media_type != e1000_media_type_copper) ||
+	    ((phy->id != M88E1543_E_PHY_ID) &&
+	    (phy->id != M88E1512_E_PHY_ID)))
+		goto out;
+
+	ret_val = e1000_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
+				       E1000_PCS_STATUS_DEV_I354,
+				       &phy_data);
+	if (ret_val)
+		goto out;
+
+	*status = phy_data & (E1000_PCS_STATUS_TX_LPI_RCVD |
+			      E1000_PCS_STATUS_RX_LPI_RCVD) ? TRUE : FALSE;
+
+out:
+	return ret_val;
+}
+
 /* Due to a hw errata, if the host tries to  configure the VFTA register
  * while performing queries from the BMC or DMA, then the VFTA in some
  * cases won't be written.
@@ -3287,4 +3640,3 @@
 	e1000_i2c_stop(hw);
 }
 
-

Modified: trunk/sys/dev/e1000/e1000_82575.h
===================================================================
--- trunk/sys/dev/e1000/e1000_82575.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_82575.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_82575.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_82575.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_82575_H_
 #define _E1000_82575_H_
@@ -246,6 +245,8 @@
 #define E1000_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009
 
 /* RSS Packet Types as indicated in the receive descriptor */
+#define E1000_RXDADV_PKTTYPE_ILMASK	0x000000F0
+#define E1000_RXDADV_PKTTYPE_TLMASK	0x00000F00
 #define E1000_RXDADV_PKTTYPE_NONE	0x00000000
 #define E1000_RXDADV_PKTTYPE_IPV4	0x00000010 /* IPV4 hdr present */
 #define E1000_RXDADV_PKTTYPE_IPV4_EX	0x00000020 /* IPV4 hdr + extensions */
@@ -479,6 +480,7 @@
 void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf);
 void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
 s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
+s32  e1000_init_hw_82575(struct e1000_hw *hw);
 
 enum e1000_promisc_type {
 	e1000_promisc_disabled = 0,   /* all promisc modes disabled */
@@ -492,7 +494,11 @@
 void e1000_rlpml_set_vf(struct e1000_hw *, u16);
 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_get_eee_status_i354(struct e1000_hw *, bool *);
+s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw);
 
 /* I2C SDA and SCL timing parameters for standard mode */
 #define E1000_I2C_T_HD_STA	4

Modified: trunk/sys/dev/e1000/e1000_api.c
===================================================================
--- trunk/sys/dev/e1000/e1000_api.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_api.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_api.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_api.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 #include "e1000_api.h"
 
@@ -294,6 +293,10 @@
 	case E1000_DEV_ID_PCH_LPT_I217_V:
 	case E1000_DEV_ID_PCH_LPTLP_I218_LM:
 	case E1000_DEV_ID_PCH_LPTLP_I218_V:
+	case E1000_DEV_ID_PCH_I218_LM2:
+	case E1000_DEV_ID_PCH_I218_V2:
+	case E1000_DEV_ID_PCH_I218_LM3:
+	case E1000_DEV_ID_PCH_I218_V3:
 		mac->type = e1000_pch_lpt;
 		break;
 	case E1000_DEV_ID_82575EB_COPPER:
@@ -330,9 +333,8 @@
 	case E1000_DEV_ID_I350_DA4:
 		mac->type = e1000_i350;
 		break;
-#if defined(QV_RELEASE) && defined(SPRINGVILLE_FLASHLESS_HW)
-	case E1000_DEV_ID_I210_NVMLESS:
-#endif /* QV_RELEASE && SPRINGVILLE_FLASHLESS_HW */
+	case E1000_DEV_ID_I210_COPPER_FLASHLESS:
+	case E1000_DEV_ID_I210_SERDES_FLASHLESS:
 	case E1000_DEV_ID_I210_COPPER:
 	case E1000_DEV_ID_I210_COPPER_OEM1:
 	case E1000_DEV_ID_I210_COPPER_IT:
@@ -353,6 +355,11 @@
 		mac->type = e1000_vfadapt_i350;
 		break;
 
+	case E1000_DEV_ID_I354_BACKPLANE_1GBPS:
+	case E1000_DEV_ID_I354_SGMII:
+	case E1000_DEV_ID_I354_BACKPLANE_2_5GBPS:
+		mac->type = e1000_i354;
+		break;
 	default:
 		/* Should never have loaded on this device */
 		ret_val = -E1000_ERR_MAC_INIT;
@@ -448,6 +455,7 @@
 	case e1000_82576:
 	case e1000_82580:
 	case e1000_i350:
+	case e1000_i354:
 		e1000_init_function_pointers_82575(hw);
 		break;
 	case e1000_i210:
@@ -824,10 +832,12 @@
  *
  *  Sets a Receive Address Register (RAR) to the specified address.
  **/
-void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
+int e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
 {
 	if (hw->mac.ops.rar_set)
-		hw->mac.ops.rar_set(hw, addr, index);
+		return hw->mac.ops.rar_set(hw, addr, index);
+
+	return E1000_SUCCESS;
 }
 
 /**

Modified: trunk/sys/dev/e1000/e1000_api.h
===================================================================
--- trunk/sys/dev/e1000/e1000_api.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_api.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_api.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_api.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_API_H_
 #define _E1000_API_H_
@@ -70,7 +69,7 @@
 s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
 s32 e1000_disable_pcie_master(struct e1000_hw *hw);
 void e1000_config_collision_dist(struct e1000_hw *hw);
-void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
+int e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
 u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
 void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
 			       u32 mc_addr_count);

Modified: trunk/sys/dev/e1000/e1000_defines.h
===================================================================
--- trunk/sys/dev/e1000/e1000_defines.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_defines.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_defines.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_defines.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_DEFINES_H_
 #define _E1000_DEFINES_H_
@@ -44,6 +43,8 @@
 /* Wake Up Control */
 #define E1000_WUC_APME		0x00000001 /* APM Enable */
 #define E1000_WUC_PME_EN	0x00000002 /* PME Enable */
+#define E1000_WUC_PME_STATUS	0x00000004 /* PME Status */
+#define E1000_WUC_APMPME	0x00000008 /* Assert PME on APM Wakeup */
 #define E1000_WUC_PHY_WAKE	0x00000100 /* if PHY supports wakeup */
 
 /* Wake Up Filter Control */
@@ -76,6 +77,7 @@
 #define E1000_CTRL_EXT_EE_RST	0x00002000 /* Reinitialize from EEPROM */
 /* Physical Func Reset Done Indication */
 #define E1000_CTRL_EXT_PFRSTD	0x00004000
+#define E1000_CTRL_EXT_SDLPE	0X00040000  /* SerDes Low Power Enable */
 #define E1000_CTRL_EXT_SPD_BYPS	0x00008000 /* Speed Select Bypass */
 #define E1000_CTRL_EXT_RO_DIS	0x00020000 /* Relaxed Ordering disable */
 #define E1000_CTRL_EXT_DMA_DYN_CLK_EN	0x00080000 /* DMA Dynamic Clk Gating */
@@ -156,6 +158,7 @@
 	E1000_RXDEXT_STATERR_CXE |	\
 	E1000_RXDEXT_STATERR_RXE)
 
+#define E1000_MRQC_ENABLE_RSS_2Q		0x00000001
 #define E1000_MRQC_RSS_FIELD_MASK		0xFFFF0000
 #define E1000_MRQC_RSS_FIELD_IPV4_TCP		0x00010000
 #define E1000_MRQC_RSS_FIELD_IPV4		0x00020000
@@ -288,7 +291,10 @@
 
 #define E1000_CONNSW_ENRGSRC		0x4
 #define E1000_CONNSW_PHYSD		0x400
+#define E1000_CONNSW_PHY_PDN		0x800
 #define E1000_CONNSW_SERDESD		0x200
+#define E1000_CONNSW_AUTOSENSE_CONF	0x2
+#define E1000_CONNSW_AUTOSENSE_EN	0x1
 #define E1000_PCS_CFG_PCS_EN		8
 #define E1000_PCS_LCTL_FLV_LINK_UP	1
 #define E1000_PCS_LCTL_FSV_10		0
@@ -326,6 +332,8 @@
 #define E1000_STATUS_GIO_MASTER_ENABLE	0x00080000 /* Master request status */
 #define E1000_STATUS_PCI66		0x00000800 /* In 66Mhz slot */
 #define E1000_STATUS_BUS64		0x00001000 /* In 64 bit slot */
+#define E1000_STATUS_2P5_SKU		0x00001000 /* Val of 2.5GBE SKU strap */
+#define E1000_STATUS_2P5_SKU_OVER	0x00002000 /* Val of 2.5GBE SKU Over */
 #define E1000_STATUS_PCIX_MODE		0x00002000 /* PCI-X mode */
 #define E1000_STATUS_PCIX_SPEED		0x0000C000 /* PCI-X bus speed */
 
@@ -337,6 +345,7 @@
 #define SPEED_10	10
 #define SPEED_100	100
 #define SPEED_1000	1000
+#define SPEED_2500	2500
 #define HALF_DUPLEX	1
 #define FULL_DUPLEX	2
 
@@ -457,6 +466,7 @@
 
 #define ETHERNET_FCS_SIZE		4
 #define MAX_JUMBO_FRAME_SIZE		0x3F00
+#define E1000_TX_PTR_GAP		0x1F
 
 /* Extended Configuration Control and Size */
 #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP	0x00000020
@@ -651,6 +661,7 @@
 #define E1000_EITR_ITR_INT_MASK	0x0000FFFF
 /* E1000_EITR_CNT_IGNR is only for 82576 and newer */
 #define E1000_EITR_CNT_IGNR	0x80000000 /* Don't reset counters on write */
+#define E1000_EITR_INTERVAL 0x00007FFC
 
 /* Transmit Descriptor Control */
 #define E1000_TXDCTL_PTHRESH	0x0000003F /* TXDCTL Prefetch Threshold */
@@ -806,6 +817,17 @@
 #define E1000_MDICNFG_PHY_MASK		0x03E00000
 #define E1000_MDICNFG_PHY_SHIFT		21
 
+#define E1000_MEDIA_PORT_COPPER			1
+#define E1000_MEDIA_PORT_OTHER			2
+#define E1000_M88E1112_AUTO_COPPER_SGMII	0x2
+#define E1000_M88E1112_AUTO_COPPER_BASEX	0x3
+#define E1000_M88E1112_STATUS_LINK		0x0004 /* Interface Link Bit */
+#define E1000_M88E1112_MAC_CTRL_1		0x10
+#define E1000_M88E1112_MAC_CTRL_1_MODE_MASK	0x0380 /* Mode Select */
+#define E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT	7
+#define E1000_M88E1112_PAGE_ADDR		0x16
+#define E1000_M88E1112_STATUS			0x01
+
 #define E1000_THSTAT_LOW_EVENT		0x20000000 /* Low thermal threshold */
 #define E1000_THSTAT_MID_EVENT		0x00200000 /* Mid thermal threshold */
 #define E1000_THSTAT_HIGH_EVENT		0x00002000 /* High thermal threshold */
@@ -822,7 +844,25 @@
 #define E1000_EEER_EEE_NEG		0x20000000 /* EEE capability nego */
 #define E1000_EEER_RX_LPI_STATUS	0x40000000 /* Rx in LPI state */
 #define E1000_EEER_TX_LPI_STATUS	0x80000000 /* Tx in LPI state */
+#define E1000_EEE_LP_ADV_ADDR_I350	0x040F     /* EEE LP Advertisement */
+#define E1000_M88E1543_PAGE_ADDR	0x16       /* Page Offset Register */
+#define E1000_M88E1543_EEE_CTRL_1	0x0
+#define E1000_M88E1543_EEE_CTRL_1_MS	0x0001     /* EEE Master/Slave */
+#define E1000_EEE_ADV_DEV_I354		7
+#define E1000_EEE_ADV_ADDR_I354		60
+#define E1000_EEE_ADV_100_SUPPORTED	(1 << 1)   /* 100BaseTx EEE Supported */
+#define E1000_EEE_ADV_1000_SUPPORTED	(1 << 2)   /* 1000BaseT EEE Supported */
+#define E1000_PCS_STATUS_DEV_I354	3
+#define E1000_PCS_STATUS_ADDR_I354	1
+#define E1000_PCS_STATUS_RX_LPI_RCVD	0x0400
+#define E1000_PCS_STATUS_TX_LPI_RCVD	0x0800
+#define E1000_M88E1512_CFG_REG_1	0x0010
+#define E1000_M88E1512_CFG_REG_2	0x0011
+#define E1000_M88E1512_CFG_REG_3	0x0007
+#define E1000_M88E1512_MODE		0x0014
 #define E1000_EEE_SU_LPI_CLK_STP	0x00800000 /* EEE LPI Clock Stop */
+#define E1000_EEE_LP_ADV_DEV_I210	7          /* EEE LP Adv Device */
+#define E1000_EEE_LP_ADV_ADDR_I210	61         /* EEE LP Adv Register */
 /* PCI Express Control */
 #define E1000_GCR_RXD_NO_SNOOP		0x00000001
 #define E1000_GCR_RXDSCW_NO_SNOOP	0x00000002
@@ -842,6 +882,8 @@
 				 E1000_GCR_TXDSCW_NO_SNOOP | \
 				 E1000_GCR_TXDSCR_NO_SNOOP)
 
+#define E1000_MMDAC_FUNC_DATA	0x4000 /* Data, no post increment */
+
 /* mPHY address control and data registers */
 #define E1000_MPHY_ADDR_CTL		0x0024 /* Address Control Reg */
 #define E1000_MPHY_ADDR_CTL_OFFSET_MASK	0xFFFF0000
@@ -1170,6 +1212,8 @@
 #define M88E1011_I_PHY_ID	0x01410C20
 #define IGP01E1000_I_PHY_ID	0x02A80380
 #define M88E1111_I_PHY_ID	0x01410CC0
+#define M88E1543_E_PHY_ID	0x01410EA0
+#define M88E1512_E_PHY_ID	0x01410DD0
 #define M88E1112_E_PHY_ID	0x01410C90
 #define I347AT4_E_PHY_ID	0x01410DC0
 #define M88E1340M_E_PHY_ID	0x01410DF0
@@ -1392,6 +1436,9 @@
 #define E1000_RXPBS_CFG_TS_EN		0x80000000 /* Timestamp in Rx buffer */
 #define E1000_RXPBS_SIZE_I210_MASK	0x0000003F /* Rx packet buffer size */
 #define E1000_TXPB0S_SIZE_I210_MASK	0x0000003F /* Tx packet buffer 0 size */
+#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 */
 
@@ -1417,4 +1464,8 @@
 /* Lan ID bit field offset in status register */
 #define E1000_STATUS_LAN_ID_OFFSET	2
 #define E1000_VFTA_ENTRIES		128
+#define E1000_UNUSEDARG
+#ifndef ERROR_REPORT
+#define ERROR_REPORT(fmt)	do { } while (0)
+#endif /* ERROR_REPORT */
 #endif /* _E1000_DEFINES_H_ */

Modified: trunk/sys/dev/e1000/e1000_hw.h
===================================================================
--- trunk/sys/dev/e1000/e1000_hw.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_hw.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_hw.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_hw.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_HW_H_
 #define _E1000_HW_H_
@@ -134,6 +133,10 @@
 #define E1000_DEV_ID_PCH_LPT_I217_V		0x153B
 #define E1000_DEV_ID_PCH_LPTLP_I218_LM		0x155A
 #define E1000_DEV_ID_PCH_LPTLP_I218_V		0x1559
+#define E1000_DEV_ID_PCH_I218_LM2		0x15A0
+#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_82576			0x10C9
 #define E1000_DEV_ID_82576_FIBER		0x10E6
 #define E1000_DEV_ID_82576_SERDES		0x10E7
@@ -166,7 +169,12 @@
 #define E1000_DEV_ID_I210_FIBER			0x1536
 #define E1000_DEV_ID_I210_SERDES		0x1537
 #define E1000_DEV_ID_I210_SGMII			0x1538
+#define E1000_DEV_ID_I210_COPPER_FLASHLESS	0x157B
+#define E1000_DEV_ID_I210_SERDES_FLASHLESS	0x157C
 #define E1000_DEV_ID_I211_COPPER		0x1539
+#define E1000_DEV_ID_I354_BACKPLANE_1GBPS	0x1F40
+#define E1000_DEV_ID_I354_SGMII			0x1F41
+#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS	0x1F45
 #define E1000_DEV_ID_DH89XXCC_SGMII		0x0438
 #define E1000_DEV_ID_DH89XXCC_SERDES		0x043A
 #define E1000_DEV_ID_DH89XXCC_BACKPLANE		0x043C
@@ -218,6 +226,7 @@
 	e1000_82576,
 	e1000_82580,
 	e1000_i350,
+	e1000_i354,
 	e1000_i210,
 	e1000_i211,
 	e1000_vfadapt,
@@ -239,6 +248,7 @@
 	e1000_nvm_eeprom_spi,
 	e1000_nvm_eeprom_microwire,
 	e1000_nvm_flash_hw,
+	e1000_nvm_invm,
 	e1000_nvm_flash_sw
 };
 
@@ -392,6 +402,10 @@
 };
 
 #define MAX_PS_BUFFERS 4
+
+/* Number of packet split data buffers (not including the header buffer) */
+#define PS_PAGE_BUFFERS	(MAX_PS_BUFFERS - 1)
+
 /* Receive Descriptor - Packet Split */
 union e1000_rx_desc_packet_split {
 	struct {
@@ -416,7 +430,8 @@
 		} middle;
 		struct {
 			__le16 header_status;
-			__le16 length[3];     /* length of buffers 1-3 */
+			/* length of buffers 1-3 */
+			__le16 length[PS_PAGE_BUFFERS];
 		} upper;
 		__le64 reserved;
 	} wb; /* writeback */
@@ -685,7 +700,7 @@
 	s32  (*setup_led)(struct e1000_hw *);
 	void (*write_vfta)(struct e1000_hw *, u32, u32);
 	void (*config_collision_dist)(struct e1000_hw *);
-	void (*rar_set)(struct e1000_hw *, u8*, u32);
+	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);
@@ -923,6 +938,13 @@
 
 #define E1000_SHADOW_RAM_WORDS		2048
 
+/* I218 PHY Ultra Low Power (ULP) states */
+enum e1000_ulp_state {
+	e1000_ulp_state_unknown,
+	e1000_ulp_state_off,
+	e1000_ulp_state_on,
+};
+
 struct e1000_dev_spec_ich8lan {
 	bool kmrn_lock_loss_workaround_enabled;
 	struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS];
@@ -931,6 +953,7 @@
 	bool nvm_k1_enabled;
 	bool eee_disable;
 	u16 eee_lp_ability;
+	enum e1000_ulp_state ulp_state;
 };
 
 struct e1000_dev_spec_82575 {
@@ -941,6 +964,8 @@
 	bool clear_semaphore_once;
 	u32 mtu;
 	struct sfp_e1000_flags eth_flags;
+	u8 media_port;
+	bool media_changed;
 };
 
 struct e1000_dev_spec_vf {

Modified: trunk/sys/dev/e1000/e1000_i210.c
===================================================================
--- trunk/sys/dev/e1000/e1000_i210.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_i210.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_i210.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_i210.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 #include "e1000_api.h"
 
@@ -43,8 +42,6 @@
 				u16 *data);
 static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
 static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
-static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
-			       u16 *data);
 
 /**
  *  e1000_acquire_nvm_i210 - Request for access to EEPROM
@@ -181,9 +178,8 @@
 	}
 
 	if (i == timeout) {
-		/*
-		 * In rare circumstances, the driver may not have released the
-		 * SW semaphore. Clear the semaphore once before giving up.
+		/* In rare circumstances, the SW semaphore may already be held
+		 * unintentionally. Clear the semaphore once before giving up.
 		 */
 		if (hw->dev_spec._82575.clear_semaphore_once) {
 			hw->dev_spec._82575.clear_semaphore_once = FALSE;
@@ -369,32 +365,76 @@
 	return ret_val;
 }
 
-/**
- *  e1000_read_nvm_i211 - Read NVM wrapper function for I211
+/** e1000_read_invm_word_i210 - Reads OTP
  *  @hw: pointer to the HW structure
  *  @address: the word address (aka eeprom offset) to read
  *  @data: pointer to the data read
  *
+ *  Reads 16-bit words from the OTP. Return error when the word is not
+ *  stored in OTP.
+ **/
+static s32 e1000_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
+{
+	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
+	u32 invm_dword;
+	u16 i;
+	u8 record_type, word_address;
+
+	DEBUGFUNC("e1000_read_invm_word_i210");
+
+	for (i = 0; i < E1000_INVM_SIZE; i++) {
+		invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
+		/* Get record type */
+		record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
+		if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
+			break;
+		if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
+			i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
+		if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
+			i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
+		if (record_type == E1000_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);
+				DEBUGOUT2("Read INVM Word 0x%02x = %x",
+					  address, *data);
+				status = E1000_SUCCESS;
+				break;
+			}
+		}
+	}
+	if (status != E1000_SUCCESS)
+		DEBUGOUT1("Requested word 0x%02x not found in OTP\n", address);
+	return status;
+}
+
+/** e1000_read_invm_i210 - Read invm wrapper function for I210/I211
+ *  @hw: pointer to the HW structure
+ *  @address: the word address (aka eeprom offset) to read
+ *  @data: pointer to the data read
+ *
  *  Wrapper function to return data formerly found in the NVM.
  **/
-static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset,
-			       u16 words, u16 *data)
+static s32 e1000_read_invm_i210(struct e1000_hw *hw, u16 offset,
+				u16 E1000_UNUSEDARG words, u16 *data)
 {
 	s32 ret_val = E1000_SUCCESS;
 
-	DEBUGFUNC("e1000_read_nvm_i211");
+	DEBUGFUNC("e1000_read_invm_i210");
 
 	/* Only the MAC addr is required to be present in the iNVM */
 	switch (offset) {
 	case NVM_MAC_ADDR:
-		ret_val = e1000_read_invm_i211(hw, (u8)offset, &data[0]);
-		ret_val |= e1000_read_invm_i211(hw, (u8)offset+1, &data[1]);
-		ret_val |= e1000_read_invm_i211(hw, (u8)offset+2, &data[2]);
+		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, &data[0]);
+		ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+1,
+						     &data[1]);
+		ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+2,
+						     &data[2]);
 		if (ret_val != E1000_SUCCESS)
 			DEBUGOUT("MAC Addr not found in iNVM\n");
 		break;
 	case NVM_INIT_CTRL_2:
-		ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
+		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
 		if (ret_val != E1000_SUCCESS) {
 			*data = NVM_INIT_CTRL_2_DEFAULT_I211;
 			ret_val = E1000_SUCCESS;
@@ -401,7 +441,7 @@
 		}
 		break;
 	case NVM_INIT_CTRL_4:
-		ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
+		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
 		if (ret_val != E1000_SUCCESS) {
 			*data = NVM_INIT_CTRL_4_DEFAULT_I211;
 			ret_val = E1000_SUCCESS;
@@ -408,7 +448,7 @@
 		}
 		break;
 	case NVM_LED_1_CFG:
-		ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
+		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
 		if (ret_val != E1000_SUCCESS) {
 			*data = NVM_LED_1_CFG_DEFAULT_I211;
 			ret_val = E1000_SUCCESS;
@@ -415,7 +455,7 @@
 		}
 		break;
 	case NVM_LED_0_2_CFG:
-		ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
+		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
 		if (ret_val != E1000_SUCCESS) {
 			*data = NVM_LED_0_2_CFG_DEFAULT_I211;
 			ret_val = E1000_SUCCESS;
@@ -422,7 +462,7 @@
 		}
 		break;
 	case NVM_ID_LED_SETTINGS:
-		ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
+		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
 		if (ret_val != E1000_SUCCESS) {
 			*data = ID_LED_RESERVED_FFFF;
 			ret_val = E1000_SUCCESS;
@@ -449,50 +489,6 @@
 }
 
 /**
- *  e1000_read_invm_i211 - Reads OTP
- *  @hw: pointer to the HW structure
- *  @address: the word address (aka eeprom offset) to read
- *  @data: pointer to the data read
- *
- *  Reads 16-bit words from the OTP. Return error when the word is not
- *  stored in OTP.
- **/
-s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, u16 *data)
-{
-	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
-	u32 invm_dword;
-	u16 i;
-	u8 record_type, word_address;
-
-	DEBUGFUNC("e1000_read_invm_i211");
-
-	for (i = 0; i < E1000_INVM_SIZE; i++) {
-		invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
-		/* Get record type */
-		record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
-		if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
-			break;
-		if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
-			i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
-		if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
-			i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
-		if (record_type == E1000_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);
-				DEBUGOUT2("Read INVM Word 0x%02x = %x",
-					  address, *data);
-				status = E1000_SUCCESS;
-				break;
-			}
-		}
-	}
-	if (status != E1000_SUCCESS)
-		DEBUGOUT1("Requested word 0x%02x not found in OTP\n", address);
-	return status;
-}
-
-/**
  *  e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum
  *  @hw: pointer to the HW structure
  *
@@ -540,7 +536,7 @@
  **/
 s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u16 checksum = 0;
 	u16 i, nvm_data;
 
@@ -593,6 +589,26 @@
 }
 
 /**
+ *  e1000_get_flash_presence_i210 - Check if flash device is detected.
+ *  @hw: pointer to the HW structure
+ *
+ **/
+bool e1000_get_flash_presence_i210(struct e1000_hw *hw)
+{
+	u32 eec = 0;
+	bool ret_val = FALSE;
+
+	DEBUGFUNC("e1000_get_flash_presence_i210");
+
+	eec = E1000_READ_REG(hw, E1000_EECD);
+
+	if (eec & E1000_EECD_FLASH_DETECTED_I210)
+		ret_val = TRUE;
+
+	return ret_val;
+}
+
+/**
  *  e1000_update_flash_i210 - Commit EEPROM to the flash
  *  @hw: pointer to the HW structure
  *
@@ -599,7 +615,7 @@
  **/
 s32 e1000_update_flash_i210(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	u32 flup;
 
 	DEBUGFUNC("e1000_update_flash_i210");
@@ -651,52 +667,36 @@
  *  e1000_init_nvm_params_i210 - Initialize i210 NVM function pointers
  *  @hw: pointer to the HW structure
  *
- *  Initialize the i210 NVM parameters and function pointers.
+ *  Initialize the i210/i211 NVM parameters and function pointers.
  **/
 static s32 e1000_init_nvm_params_i210(struct e1000_hw *hw)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 	struct e1000_nvm_info *nvm = &hw->nvm;
 
 	DEBUGFUNC("e1000_init_nvm_params_i210");
 
 	ret_val = e1000_init_nvm_params_82575(hw);
-
 	nvm->ops.acquire = e1000_acquire_nvm_i210;
 	nvm->ops.release = e1000_release_nvm_i210;
-	nvm->ops.read    = e1000_read_nvm_srrd_i210;
-	nvm->ops.write   = e1000_write_nvm_srwr_i210;
 	nvm->ops.valid_led_default = e1000_valid_led_default_i210;
-	nvm->ops.validate = e1000_validate_nvm_checksum_i210;
-	nvm->ops.update   = e1000_update_nvm_checksum_i210;
-
+	if (e1000_get_flash_presence_i210(hw)) {
+		hw->nvm.type = e1000_nvm_flash_hw;
+		nvm->ops.read    = e1000_read_nvm_srrd_i210;
+		nvm->ops.write   = e1000_write_nvm_srwr_i210;
+		nvm->ops.validate = e1000_validate_nvm_checksum_i210;
+		nvm->ops.update   = e1000_update_nvm_checksum_i210;
+	} else {
+		hw->nvm.type = e1000_nvm_invm;
+		nvm->ops.read     = e1000_read_invm_i210;
+		nvm->ops.write    = e1000_null_write_nvm;
+		nvm->ops.validate = e1000_null_ops_generic;
+		nvm->ops.update   = e1000_null_ops_generic;
+	}
 	return ret_val;
 }
 
 /**
- *  e1000_init_nvm_params_i211 - Initialize i211 NVM function pointers
- *  @hw: pointer to the HW structure
- *
- *  Initialize the NVM parameters and function pointers for i211.
- **/
-static s32 e1000_init_nvm_params_i211(struct e1000_hw *hw)
-{
-	struct e1000_nvm_info *nvm = &hw->nvm;
-
-	DEBUGFUNC("e1000_init_nvm_params_i211");
-
-	nvm->ops.acquire  = e1000_acquire_nvm_i210;
-	nvm->ops.release  = e1000_release_nvm_i210;
-	nvm->ops.read     = e1000_read_nvm_i211;
-	nvm->ops.valid_led_default = e1000_valid_led_default_i210;
-	nvm->ops.write    = e1000_null_write_nvm;
-	nvm->ops.validate = e1000_null_ops_generic;
-	nvm->ops.update   = e1000_null_ops_generic;
-
-	return E1000_SUCCESS;
-}
-
-/**
  *  e1000_init_function_pointers_i210 - Init func ptrs.
  *  @hw: pointer to the HW structure
  *
@@ -705,17 +705,8 @@
 void e1000_init_function_pointers_i210(struct e1000_hw *hw)
 {
 	e1000_init_function_pointers_82575(hw);
+	hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
 
-	switch (hw->mac.type) {
-	case e1000_i210:
-		hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
-		break;
-	case e1000_i211:
-		hw->nvm.ops.init_params = e1000_init_nvm_params_i211;
-		break;
-	default:
-		break;
-	}
 	return;
 }
 
@@ -753,3 +744,161 @@
 out:
 	return ret_val;
 }
+
+/**
+ *  __e1000_access_xmdio_reg - Read/write XMDIO register
+ *  @hw: pointer to the HW structure
+ *  @address: XMDIO address to program
+ *  @dev_addr: device address to program
+ *  @data: pointer to value to read/write from/to the XMDIO address
+ *  @read: boolean flag to indicate read or write
+ **/
+static s32 __e1000_access_xmdio_reg(struct e1000_hw *hw, u16 address,
+				    u8 dev_addr, u16 *data, bool read)
+{
+	s32 ret_val;
+
+	DEBUGFUNC("__e1000_access_xmdio_reg");
+
+	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
+	if (ret_val)
+		return ret_val;
+
+	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
+	if (ret_val)
+		return ret_val;
+
+	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
+							 dev_addr);
+	if (ret_val)
+		return ret_val;
+
+	if (read)
+		ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
+	else
+		ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
+	if (ret_val)
+		return ret_val;
+
+	/* Recalibrate the device back to 0 */
+	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
+	if (ret_val)
+		return ret_val;
+
+	return ret_val;
+}
+
+/**
+ *  e1000_read_xmdio_reg - Read XMDIO register
+ *  @hw: pointer to the HW structure
+ *  @addr: XMDIO address to program
+ *  @dev_addr: device address to program
+ *  @data: value to be read from the EMI address
+ **/
+s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
+{
+	DEBUGFUNC("e1000_read_xmdio_reg");
+
+	return __e1000_access_xmdio_reg(hw, addr, dev_addr, data, TRUE);
+}
+
+/**
+ *  e1000_write_xmdio_reg - Write XMDIO register
+ *  @hw: pointer to the HW structure
+ *  @addr: XMDIO address to program
+ *  @dev_addr: device address to program
+ *  @data: value to be written to the XMDIO address
+ **/
+s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
+{
+	DEBUGFUNC("e1000_read_xmdio_reg");
+
+	return __e1000_access_xmdio_reg(hw, addr, dev_addr, &data, FALSE);
+}
+
+/**
+ * e1000_pll_workaround_i210
+ * @hw: pointer to the HW structure
+ *
+ * Works around an errata in the PLL circuit where it occasionally
+ * provides the wrong clock frequency after power up.
+ **/
+static s32 e1000_pll_workaround_i210(struct e1000_hw *hw)
+{
+	s32 ret_val;
+	u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
+	u16 nvm_word, phy_word, pci_word, tmp_nvm;
+	int i;
+
+	/* Get and set needed register values */
+	wuc = E1000_READ_REG(hw, E1000_WUC);
+	mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
+	reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
+	E1000_WRITE_REG(hw, E1000_MDICNFG, reg_val);
+
+	/* Get data from NVM, or set default */
+	ret_val = e1000_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
+					    &nvm_word);
+	if (ret_val != E1000_SUCCESS)
+		nvm_word = E1000_INVM_DEFAULT_AL;
+	tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
+	for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
+		/* check current state directly from internal PHY */
+		e1000_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE |
+					 E1000_PHY_PLL_FREQ_REG), &phy_word);
+		if ((phy_word & E1000_PHY_PLL_UNCONF)
+		    != E1000_PHY_PLL_UNCONF) {
+			ret_val = E1000_SUCCESS;
+			break;
+		} else {
+			ret_val = -E1000_ERR_PHY;
+		}
+		/* directly reset the internal PHY */
+		ctrl = E1000_READ_REG(hw, E1000_CTRL);
+		E1000_WRITE_REG(hw, E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);
+
+		ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
+		ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
+		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
+
+		E1000_WRITE_REG(hw, E1000_WUC, 0);
+		reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
+		E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val);
+
+		e1000_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+		pci_word |= E1000_PCI_PMCSR_D3;
+		e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+		msec_delay(1);
+		pci_word &= ~E1000_PCI_PMCSR_D3;
+		e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+		reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
+		E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val);
+
+		/* restore WUC register */
+		E1000_WRITE_REG(hw, E1000_WUC, wuc);
+	}
+	/* restore MDICNFG setting */
+	E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
+	return ret_val;
+}
+
+/**
+ *  e1000_init_hw_i210 - Init hw for I210/I211
+ *  @hw: pointer to the HW structure
+ *
+ *  Called to initialize hw for i210 hw family.
+ **/
+s32 e1000_init_hw_i210(struct e1000_hw *hw)
+{
+	s32 ret_val;
+
+	DEBUGFUNC("e1000_init_hw_i210");
+	if ((hw->mac.type >= e1000_i210) &&
+	    !(e1000_get_flash_presence_i210(hw))) {
+		ret_val = e1000_pll_workaround_i210(hw);
+		if (ret_val != E1000_SUCCESS)
+			return ret_val;
+	}
+	ret_val = e1000_init_hw_82575(hw);
+	return ret_val;
+}

Modified: trunk/sys/dev/e1000/e1000_i210.h
===================================================================
--- trunk/sys/dev/e1000/e1000_i210.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_i210.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,11 +30,12 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_i210.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_i210.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_I210_H_
 #define _E1000_I210_H_
 
+bool e1000_get_flash_presence_i210(struct e1000_hw *hw);
 s32 e1000_update_flash_i210(struct e1000_hw *hw);
 s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw);
 s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw);
@@ -43,9 +43,13 @@
 			      u16 words, u16 *data);
 s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
 			     u16 words, u16 *data);
-s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, u16 *data);
 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,
+			 u16 *data);
+s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
+			  u16 data);
+s32 e1000_init_hw_i210(struct e1000_hw *hw);
 
 #define E1000_STM_OPCODE		0xDB00
 #define E1000_EEPROM_FLASH_SIZE_WORD	0x11
@@ -83,7 +87,7 @@
 					 (ID_LED_OFF1_OFF2))
 #define ID_LED_DEFAULT_I210_SERDES	((ID_LED_DEF1_DEF2 << 8) | \
 					 (ID_LED_DEF1_DEF2 <<  4) | \
-					 (ID_LED_DEF1_DEF2))
+					 (ID_LED_OFF1_ON2))
 
 /* NVM offset defaults for I211 devices */
 #define NVM_INIT_CTRL_2_DEFAULT_I211	0X7243
@@ -90,4 +94,16 @@
 #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
+
+/* PLL Defines */
+#define E1000_PCI_PMCSR			0x44
+#define E1000_PCI_PMCSR_D3		0x03
+#define E1000_MAX_PLL_TRIES		5
+#define E1000_PHY_PLL_UNCONF		0xFF
+#define E1000_PHY_PLL_FREQ_PAGE		0xFC0000
+#define E1000_PHY_PLL_FREQ_REG		0x000E
+#define E1000_INVM_DEFAULT_AL		0x202F
+#define E1000_INVM_AUTOLOAD		0x0A
+#define E1000_INVM_PLL_WO_VAL		0x0010
+
 #endif

Modified: trunk/sys/dev/e1000/e1000_ich8lan.c
===================================================================
--- trunk/sys/dev/e1000/e1000_ich8lan.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_ich8lan.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_ich8lan.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_ich8lan.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 /* 82562G 10/100 Network Connection
  * 82562G-2 10/100 Network Connection
@@ -60,6 +59,14 @@
  * 82578DC Gigabit Network Connection
  * 82579LM Gigabit Network Connection
  * 82579V Gigabit Network Connection
+ * Ethernet Connection I217-LM
+ * Ethernet Connection I217-V
+ * Ethernet Connection I218-V
+ * Ethernet Connection I218-LM
+ * Ethernet Connection (2) I218-LM
+ * Ethernet Connection (2) I218-V
+ * Ethernet Connection (3) I218-LM
+ * Ethernet Connection (3) I218-V
  */
 
 #include "e1000_api.h"
@@ -70,8 +77,9 @@
 static void e1000_release_nvm_ich8lan(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
-static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
-static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index);
+static int  e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
+static int  e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index);
+static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw);
 static void e1000_update_mc_addr_list_pch2lan(struct e1000_hw *hw,
 					      u8 *mc_addr_list,
 					      u32 mc_addr_count);
@@ -182,8 +190,9 @@
 {
 	u16 phy_reg = 0;
 	u32 phy_id = 0;
-	s32 ret_val;
+	s32 ret_val = 0;
 	u16 retry_count;
+	u32 mac_reg = 0;
 
 	for (retry_count = 0; retry_count < 2; retry_count++) {
 		ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_reg);
@@ -202,26 +211,87 @@
 
 	if (hw->phy.id) {
 		if  (hw->phy.id == phy_id)
-			return TRUE;
+			goto out;
 	} else if (phy_id) {
 		hw->phy.id = phy_id;
 		hw->phy.revision = (u32)(phy_reg & ~PHY_REVISION_MASK);
-		return TRUE;
+		goto out;
 	}
 
 	/* In case the PHY needs to be in mdio slow mode,
 	 * set slow mode and try to get the PHY id again.
 	 */
-	hw->phy.ops.release(hw);
-	ret_val = e1000_set_mdio_slow_mode_hv(hw);
-	if (!ret_val)
-		ret_val = e1000_get_phy_id(hw);
-	hw->phy.ops.acquire(hw);
+	if (hw->mac.type < e1000_pch_lpt) {
+		hw->phy.ops.release(hw);
+		ret_val = e1000_set_mdio_slow_mode_hv(hw);
+		if (!ret_val)
+			ret_val = e1000_get_phy_id(hw);
+		hw->phy.ops.acquire(hw);
+	}
 
-	return !ret_val;
+	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);
+
+		/* 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;
 }
 
 /**
+ *  e1000_toggle_lanphypc_pch_lpt - toggle the LANPHYPC pin value
+ *  @hw: pointer to the HW structure
+ *
+ *  Toggling the LANPHYPC pin value fully power-cycles the PHY and is
+ *  used to reset the PHY to a quiescent state when necessary.
+ **/
+static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw)
+{
+	u32 mac_reg;
+
+	DEBUGFUNC("e1000_toggle_lanphypc_pch_lpt");
+
+	/* Set Phy Config Counter to 50msec */
+	mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM3);
+	mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK;
+	mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC;
+	E1000_WRITE_REG(hw, E1000_FEXTNVM3, mac_reg);
+
+	/* Toggle LANPHYPC Value bit */
+	mac_reg = E1000_READ_REG(hw, E1000_CTRL);
+	mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE;
+	mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE;
+	E1000_WRITE_REG(hw, E1000_CTRL, mac_reg);
+	E1000_WRITE_FLUSH(hw);
+	usec_delay(10);
+	mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
+	E1000_WRITE_REG(hw, E1000_CTRL, mac_reg);
+	E1000_WRITE_FLUSH(hw);
+
+	if (hw->mac.type < e1000_pch_lpt) {
+		msec_delay(50);
+	} else {
+		u16 count = 20;
+
+		do {
+			msec_delay(5);
+		} while (!(E1000_READ_REG(hw, E1000_CTRL_EXT) &
+			   E1000_CTRL_EXT_LPCD) && count--);
+
+		msec_delay(30);
+	}
+}
+
+/**
  *  e1000_init_phy_workarounds_pchlan - PHY initialization workarounds
  *  @hw: pointer to the HW structure
  *
@@ -232,7 +302,6 @@
 {
 	u32 mac_reg, fwsm = E1000_READ_REG(hw, E1000_FWSM);
 	s32 ret_val;
-	u16 phy_reg;
 
 	DEBUGFUNC("e1000_init_phy_workarounds_pchlan");
 
@@ -241,6 +310,12 @@
 	 */
 	e1000_gate_hw_phy_config_ich8lan(hw, TRUE);
 
+	/* It is not possible to be certain of the current state of ULP
+	 * so forcibly disable it.
+	 */
+	hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_unknown;
+	e1000_disable_ulp_lpt_lp(hw, TRUE);
+
 	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val) {
 		DEBUGOUT("Failed to initialize PHY flow\n");
@@ -263,24 +338,16 @@
 		mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg);
 
+		/* Wait 50 milliseconds for MAC to finish any retries
+		 * that it might be trying to perform from previous
+		 * attempts to acknowledge any phy read requests.
+		 */
+		 msec_delay(50);
+
 		/* fall-through */
 	case e1000_pch2lan:
-		if (e1000_phy_is_accessible_pchlan(hw)) {
-			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);
-
-				/* 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);
-			}
+		if (e1000_phy_is_accessible_pchlan(hw))
 			break;
-		}
 
 		/* fall-through */
 	case e1000_pchlan:
@@ -290,44 +357,27 @@
 
 		if (hw->phy.ops.check_reset_block(hw)) {
 			DEBUGOUT("Required LANPHYPC toggle blocked by ME\n");
+			ret_val = -E1000_ERR_PHY;
 			break;
 		}
 
-		DEBUGOUT("Toggling LANPHYPC\n");
+		/* Toggle LANPHYPC Value bit */
+		e1000_toggle_lanphypc_pch_lpt(hw);
+		if (hw->mac.type >= e1000_pch_lpt) {
+			if (e1000_phy_is_accessible_pchlan(hw))
+				break;
 
-		/* Set Phy Config Counter to 50msec */
-		mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM3);
-		mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK;
-		mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC;
-		E1000_WRITE_REG(hw, E1000_FEXTNVM3, mac_reg);
-
-		if (hw->mac.type == e1000_pch_lpt) {
 			/* Toggling LANPHYPC brings the PHY out of SMBus mode
-			 * So ensure that the MAC is also out of SMBus mode
+			 * so ensure that the MAC is also out of SMBus mode
 			 */
 			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);
-		}
 
-		/* Toggle LANPHYPC Value bit */
-		mac_reg = E1000_READ_REG(hw, E1000_CTRL);
-		mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE;
-		mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE;
-		E1000_WRITE_REG(hw, E1000_CTRL, mac_reg);
-		E1000_WRITE_FLUSH(hw);
-		usec_delay(10);
-		mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
-		E1000_WRITE_REG(hw, E1000_CTRL, mac_reg);
-		E1000_WRITE_FLUSH(hw);
-		if (hw->mac.type < e1000_pch_lpt) {
-			msec_delay(50);
-		} else {
-			u16 count = 20;
-			do {
-				msec_delay(5);
-			} while (!(E1000_READ_REG(hw, E1000_CTRL_EXT) &
-				   E1000_CTRL_EXT_LPCD) && count--);
+			if (e1000_phy_is_accessible_pchlan(hw))
+				break;
+
+			ret_val = -E1000_ERR_PHY;
 		}
 		break;
 	default:
@@ -335,14 +385,34 @@
 	}
 
 	hw->phy.ops.release(hw);
+	if (!ret_val) {
 
-	/* Reset the PHY before any access to it.  Doing so, ensures
-	 * that the PHY is in a known good state before we read/write
-	 * PHY registers.  The generic reset is sufficient here,
-	 * because we haven't determined the PHY type yet.
-	 */
-	ret_val = e1000_phy_hw_reset_generic(hw);
+		/* Check to see if able to reset PHY.  Print error if not */
+		if (hw->phy.ops.check_reset_block(hw)) {
+			ERROR_REPORT("Reset blocked by ME\n");
+			goto out;
+		}
 
+		/* Reset the PHY before any access to it.  Doing so, ensures
+		 * that the PHY is in a known good state before we read/write
+		 * PHY registers.  The generic reset is sufficient here,
+		 * because we haven't determined the PHY type yet.
+		 */
+		ret_val = e1000_phy_hw_reset_generic(hw);
+		if (ret_val)
+			goto out;
+
+		/* On a successful reset, possibly need to wait for the PHY
+		 * to quiesce to an accessible state before returning control
+		 * to the calling function.  If the PHY does not quiesce, then
+		 * return E1000E_BLK_PHY_RESET, as this is the condition that
+		 *  the PHY is in.
+		 */
+		ret_val = hw->phy.ops.check_reset_block(hw);
+		if (ret_val)
+			ERROR_REPORT("ME blocked access to PHY after reset\n");
+	}
+
 out:
 	/* Ungate automatic PHY configuration on non-managed 82579 */
 	if ((hw->mac.type == e1000_pch2lan) &&
@@ -551,13 +621,12 @@
 	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;
 	}
 
-	nvm->type = e1000_nvm_flash_sw;
-
 	gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
 
 	/* sector_X_addr is a "sector"-aligned address (4096 bytes)
@@ -573,8 +642,8 @@
 	/* 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 = ((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);
@@ -767,7 +836,7 @@
  *
  *  Assumes the SW/FW/HW Semaphore is already acquired.
  **/
-static s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data)
+s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data)
 {
 	DEBUGFUNC("e1000_read_emi_reg_locked");
 
@@ -781,18 +850,35 @@
  *  Enable/disable EEE based on setting in dev_spec structure, the duplex of
  *  the link and the EEE capabilities of the link partner.  The LPI Control
  *  register bits will remain set only if/when link is up.
+ *
+ *  EEE LPI must not be asserted earlier than one second after link is up.
+ *  On 82579, EEE LPI should not be enabled until such time otherwise there
+ *  can be link issues with some switches.  Other devices can have EEE LPI
+ *  enabled immediately upon link up since they have a timer in hardware which
+ *  prevents LPI from being asserted too early.
  **/
-static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
+s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
 {
 	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
 	s32 ret_val;
-	u16 lpi_ctrl;
+	u16 lpa, pcs_status, adv, adv_addr, lpi_ctrl, data;
 
 	DEBUGFUNC("e1000_set_eee_pchlan");
 
-	if ((hw->phy.type != e1000_phy_82579) &&
-	    (hw->phy.type != e1000_phy_i217))
+	switch (hw->phy.type) {
+	case e1000_phy_82579:
+		lpa = I82579_EEE_LP_ABILITY;
+		pcs_status = I82579_EEE_PCS_STATUS;
+		adv_addr = I82579_EEE_ADVERTISEMENT;
+		break;
+	case e1000_phy_i217:
+		lpa = I217_EEE_LP_ABILITY;
+		pcs_status = I217_EEE_PCS_STATUS;
+		adv_addr = I217_EEE_ADVERTISEMENT;
+		break;
+	default:
 		return E1000_SUCCESS;
+	}
 
 	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
@@ -807,34 +893,24 @@
 
 	/* Enable EEE if not disabled by user */
 	if (!dev_spec->eee_disable) {
-		u16 lpa, pcs_status, data;
-
 		/* Save off link partner's EEE ability */
-		switch (hw->phy.type) {
-		case e1000_phy_82579:
-			lpa = I82579_EEE_LP_ABILITY;
-			pcs_status = I82579_EEE_PCS_STATUS;
-			break;
-		case e1000_phy_i217:
-			lpa = I217_EEE_LP_ABILITY;
-			pcs_status = I217_EEE_PCS_STATUS;
-			break;
-		default:
-			ret_val = -E1000_ERR_PHY;
-			goto release;
-		}
 		ret_val = e1000_read_emi_reg_locked(hw, lpa,
 						    &dev_spec->eee_lp_ability);
 		if (ret_val)
 			goto release;
 
+		/* Read EEE advertisement */
+		ret_val = e1000_read_emi_reg_locked(hw, adv_addr, &adv);
+		if (ret_val)
+			goto release;
+
 		/* Enable EEE only for speeds in which the link partner is
-		 * EEE capable.
+		 * EEE capable and for which we advertise EEE.
 		 */
-		if (dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED)
+		if (adv & dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED)
 			lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE;
 
-		if (dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) {
+		if (adv & dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) {
 			hw->phy.ops.read_reg_locked(hw, PHY_LP_ABILITY, &data);
 			if (data & NWAY_LPAR_100TX_FD_CAPS)
 				lpi_ctrl |= I82579_LPI_CTRL_100_ENABLE;
@@ -846,13 +922,24 @@
 				dev_spec->eee_lp_ability &=
 				    ~I82579_EEE_100_SUPPORTED;
 		}
+	}
 
-		/* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */
-		ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data);
+	if (hw->phy.type == e1000_phy_82579) {
+		ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
+						    &data);
 		if (ret_val)
 			goto release;
+
+		data &= ~I82579_LPI_100_PLL_SHUT;
+		ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
+						     data);
 	}
 
+	/* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */
+	ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data);
+	if (ret_val)
+		goto release;
+
 	ret_val = hw->phy.ops.write_reg_locked(hw, I82579_LPI_CTRL, lpi_ctrl);
 release:
 	hw->phy.ops.release(hw);
@@ -868,16 +955,17 @@
  *  When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications
  *  preventing further DMA write requests.  Workaround the issue by disabling
  *  the de-assertion of the clock request when in 1Gpbs mode.
+ *  Also, set appropriate Tx re-transmission timeouts for 10 and 100Half link
+ *  speeds in order to avoid Tx hangs.
  **/
 static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
 {
 	u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
+	u32 status = E1000_READ_REG(hw, E1000_STATUS);
 	s32 ret_val = E1000_SUCCESS;
+	u16 reg;
 
-	if (link && (E1000_READ_REG(hw, E1000_STATUS) &
-		     E1000_STATUS_SPEED_1000)) {
-		u16 kmrn_reg;
-
+	if (link && (status & E1000_STATUS_SPEED_1000)) {
 		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
 			return ret_val;
@@ -884,7 +972,7 @@
 
 		ret_val =
 		    e1000_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG,
-					       &kmrn_reg);
+					       &reg);
 		if (ret_val)
 			goto release;
 
@@ -891,7 +979,7 @@
 		ret_val =
 		    e1000_write_kmrn_reg_locked(hw,
 						E1000_KMRNCTRLSTA_K1_CONFIG,
-						kmrn_reg &
+						reg &
 						~E1000_KMRNCTRLSTA_K1_ENABLE);
 		if (ret_val)
 			goto release;
@@ -904,13 +992,45 @@
 		ret_val =
 		    e1000_write_kmrn_reg_locked(hw,
 						E1000_KMRNCTRLSTA_K1_CONFIG,
-						kmrn_reg);
+						reg);
 release:
 		hw->phy.ops.release(hw);
 	} else {
 		/* clear FEXTNVM6 bit 8 on link down or 10/100 */
-		E1000_WRITE_REG(hw, E1000_FEXTNVM6,
-				fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK);
+		fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK;
+
+		if (!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);
+		if (ret_val)
+			return ret_val;
+
+		/* Clear link status transmit timeout */
+		reg &= ~I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK;
+
+		if (status & E1000_STATUS_SPEED_100) {
+			/* Set inband Tx timeout to 5x10us for 100Half */
+			reg |= 5 << I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT;
+
+			/* Do not extend the K1 entry latency for 100Half */
+			fextnvm6 &= ~E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION;
+		} else {
+			/* Set inband Tx timeout to 50x10us for 10Full/Half */
+			reg |= 50 <<
+			       I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT;
+
+			/* Extend the K1 entry latency for 10 Mbps */
+			fextnvm6 |= E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION;
+		}
+
+		ret_val = hw->phy.ops.write_reg(hw, I217_INBAND_CTRL, reg);
+		if (ret_val)
+			return ret_val;
+
+update_fextnvm6:
+		E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6);
 	}
 
 	return ret_val;
@@ -1019,7 +1139,6 @@
 			lat_ns /= 1000000000;
 			obff_hwm = (s32)(rxa - lat_ns);
 		}
-
 		if ((obff_hwm < 0) || (obff_hwm > E1000_SVT_OFF_HWM_MASK)) {
 			DEBUGOUT1("Invalid high water mark %d\n", obff_hwm);
 			return -E1000_ERR_CONFIG;
@@ -1080,6 +1199,256 @@
 }
 
 /**
+ *  e1000_enable_ulp_lpt_lp - configure Ultra Low Power mode for LynxPoint-LP
+ *  @hw: pointer to the HW structure
+ *  @to_sx: boolean indicating a system power state transition to Sx
+ *
+ *  When link is down, configure ULP mode to significantly reduce the power
+ *  to the PHY.  If on a Manageability Engine (ME) enabled system, tell the
+ *  ME firmware to start the ULP configuration.  If not on an ME enabled
+ *  system, configure the ULP mode by software.
+ */
+s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
+{
+	u32 mac_reg;
+	s32 ret_val = E1000_SUCCESS;
+	u16 phy_reg;
+
+	if ((hw->mac.type < e1000_pch_lpt) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_I218_LM2) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_I218_V2) ||
+	    (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_on))
+		return 0;
+
+	if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) {
+		/* Request ME configure ULP mode in the PHY */
+		mac_reg = E1000_READ_REG(hw, E1000_H2ME);
+		mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS;
+		E1000_WRITE_REG(hw, E1000_H2ME, mac_reg);
+
+		goto out;
+	}
+
+	if (!to_sx) {
+		int i = 0;
+
+		/* Poll up to 5 seconds for Cable Disconnected indication */
+		while (!(E1000_READ_REG(hw, E1000_FEXT) &
+			 E1000_FEXT_PHY_CABLE_DISCONNECTED)) {
+			/* Bail if link is re-acquired */
+			if (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)
+				return -E1000_ERR_PHY;
+
+			if (i++ == 100)
+				break;
+
+			msec_delay(50);
+		}
+		DEBUGOUT2("CABLE_DISCONNECTED %s set after %dmsec\n",
+			 (E1000_READ_REG(hw, E1000_FEXT) &
+			  E1000_FEXT_PHY_CABLE_DISCONNECTED) ? "" : "not",
+			 i * 50);
+	}
+
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val)
+		goto out;
+
+	/* Force SMBus mode in PHY */
+	ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
+	if (ret_val)
+		goto release;
+	phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
+	e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
+
+	/* Force 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);
+
+	/* Set Inband ULP Exit, Reset to SMBus mode and
+	 * Disable SMBus Release on PERST# in PHY
+	 */
+	ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg);
+	if (ret_val)
+		goto release;
+	phy_reg |= (I218_ULP_CONFIG1_RESET_TO_SMBUS |
+		    I218_ULP_CONFIG1_DISABLE_SMB_PERST);
+	if (to_sx) {
+		if (E1000_READ_REG(hw, E1000_WUFC) & E1000_WUFC_LNKC)
+			phy_reg |= I218_ULP_CONFIG1_WOL_HOST;
+
+		phy_reg |= I218_ULP_CONFIG1_STICKY_ULP;
+	} else {
+		phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT;
+	}
+	e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
+
+	/* Set Disable SMBus Release on PERST# in MAC */
+	mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7);
+	mac_reg |= E1000_FEXTNVM7_DISABLE_SMB_PERST;
+	E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg);
+
+	/* Commit ULP changes in PHY by starting auto ULP configuration */
+	phy_reg |= I218_ULP_CONFIG1_START;
+	e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
+release:
+	hw->phy.ops.release(hw);
+out:
+	if (ret_val) {
+		DEBUGOUT1("Error in ULP enable flow: %d\n", ret_val);
+	} else
+		hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_on;
+
+	return ret_val;
+}
+
+/**
+ *  e1000_disable_ulp_lpt_lp - unconfigure Ultra Low Power mode for LynxPoint-LP
+ *  @hw: pointer to the HW structure
+ *  @force: boolean indicating whether or not to force disabling ULP
+ *
+ *  Un-configure ULP mode when link is up, the system is transitioned from
+ *  Sx or the driver is unloaded.  If on a Manageability Engine (ME) enabled
+ *  system, poll for an indication from ME that ULP has been un-configured.
+ *  If not on an ME enabled system, un-configure the ULP mode by software.
+ *
+ *  During nominal operation, this function is called when link is acquired
+ *  to disable ULP mode (force=FALSE); otherwise, for example when unloading
+ *  the driver or during Sx->S0 transitions, this is called with force=TRUE
+ *  to forcibly disable ULP.
+ */
+s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force)
+{
+	s32 ret_val = E1000_SUCCESS;
+	u32 mac_reg;
+	u16 phy_reg;
+	int i = 0;
+
+	if ((hw->mac.type < e1000_pch_lpt) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_I218_LM2) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_I218_V2) ||
+	    (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_off))
+		return 0;
+
+	if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) {
+		if (force) {
+			/* Request ME un-configure ULP mode in the PHY */
+			mac_reg = E1000_READ_REG(hw, E1000_H2ME);
+			mac_reg &= ~E1000_H2ME_ULP;
+			mac_reg |= E1000_H2ME_ENFORCE_SETTINGS;
+			E1000_WRITE_REG(hw, E1000_H2ME, mac_reg);
+		}
+
+		/* Poll up to 100msec for ME to clear ULP_CFG_DONE */
+		while (E1000_READ_REG(hw, E1000_FWSM) &
+		       E1000_FWSM_ULP_CFG_DONE) {
+			if (i++ == 10) {
+				ret_val = -E1000_ERR_PHY;
+				goto out;
+			}
+
+			msec_delay(10);
+		}
+		DEBUGOUT1("ULP_CONFIG_DONE cleared after %dmsec\n", i * 10);
+
+		if (force) {
+			mac_reg = E1000_READ_REG(hw, E1000_H2ME);
+			mac_reg &= ~E1000_H2ME_ENFORCE_SETTINGS;
+			E1000_WRITE_REG(hw, E1000_H2ME, mac_reg);
+		} else {
+			/* Clear H2ME.ULP after ME ULP configuration */
+			mac_reg = E1000_READ_REG(hw, E1000_H2ME);
+			mac_reg &= ~E1000_H2ME_ULP;
+			E1000_WRITE_REG(hw, E1000_H2ME, mac_reg);
+		}
+
+		goto out;
+	}
+
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val)
+		goto out;
+
+	if (force)
+		/* Toggle LANPHYPC Value bit */
+		e1000_toggle_lanphypc_pch_lpt(hw);
+
+	/* Unforce SMBus mode in PHY */
+	ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
+	if (ret_val) {
+		/* The MAC might be in PCIe mode, so temporarily force to
+		 * SMBus mode in order to access the PHY.
+		 */
+		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);
+
+		msec_delay(50);
+
+		ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL,
+						       &phy_reg);
+		if (ret_val)
+			goto release;
+	}
+	phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
+	e1000_write_phy_reg_hv_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);
+
+	/* When ULP mode was previously entered, K1 was disabled by the
+	 * hardware.  Re-Enable K1 in the PHY when exiting ULP.
+	 */
+	ret_val = e1000_read_phy_reg_hv_locked(hw, HV_PM_CTRL, &phy_reg);
+	if (ret_val)
+		goto release;
+	phy_reg |= HV_PM_CTRL_K1_ENABLE;
+	e1000_write_phy_reg_hv_locked(hw, HV_PM_CTRL, phy_reg);
+
+	/* Clear ULP enabled configuration */
+	ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg);
+	if (ret_val)
+		goto release;
+		phy_reg &= ~(I218_ULP_CONFIG1_IND |
+			     I218_ULP_CONFIG1_STICKY_ULP |
+			     I218_ULP_CONFIG1_RESET_TO_SMBUS |
+			     I218_ULP_CONFIG1_WOL_HOST |
+			     I218_ULP_CONFIG1_INBAND_EXIT |
+			     I218_ULP_CONFIG1_DISABLE_SMB_PERST);
+		e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
+
+		/* Commit ULP changes by starting auto ULP configuration */
+		phy_reg |= I218_ULP_CONFIG1_START;
+		e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
+
+		/* Clear Disable SMBus Release on PERST# in MAC */
+		mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7);
+		mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST;
+		E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg);
+
+release:
+	hw->phy.ops.release(hw);
+	if (force) {
+		hw->phy.ops.reset(hw);
+		msec_delay(50);
+	}
+out:
+	if (ret_val) {
+		DEBUGOUT1("Error in ULP disable flow: %d\n", ret_val);
+	} else
+		hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_off;
+
+	return ret_val;
+}
+
+/**
  *  e1000_check_for_copper_link_ich8lan - Check for link (Copper)
  *  @hw: pointer to the HW structure
  *
@@ -1104,13 +1473,13 @@
 	if (!mac->get_link_status)
 		return E1000_SUCCESS;
 
-	/* First we want to see if the MII Status Register reports
-	 * link.  If so, then we want to get the current speed/duplex
-	 * of the PHY.
-	 */
-	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
-	if (ret_val)
-		return ret_val;
+		/* First we want to see if the MII Status Register reports
+		 * link.  If so, then we want to get the current speed/duplex
+		 * of the PHY.
+		 */
+		ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
+		if (ret_val)
+			return ret_val;
 
 	if (hw->mac.type == e1000_pchlan) {
 		ret_val = e1000_k1_gig_workaround_hv(hw, link);
@@ -1118,14 +1487,17 @@
 			return ret_val;
 	}
 
-	/* When connected at 10Mbps half-duplex, 82579 parts are excessively
+	/* When connected at 10Mbps half-duplex, some parts are excessively
 	 * aggressive resulting in many collisions. To avoid this, increase
 	 * the IPG and reduce Rx latency in the PHY.
 	 */
-	if ((hw->mac.type == e1000_pch2lan) && link) {
+	if (((hw->mac.type == e1000_pch2lan) ||
+	     (hw->mac.type == e1000_pch_lpt)) && link) {
 		u32 reg;
 		reg = E1000_READ_REG(hw, E1000_STATUS);
 		if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) {
+			u16 emi_addr;
+
 			reg = E1000_READ_REG(hw, E1000_TIPG);
 			reg &= ~E1000_TIPG_IPGT_MASK;
 			reg |= 0xFF;
@@ -1136,7 +1508,11 @@
 			if (ret_val)
 				return ret_val;
 
-			ret_val = e1000_write_emi_reg_locked(hw, I82579_RX_CONFIG, 0);
+			if (hw->mac.type == e1000_pch2lan)
+				emi_addr = I82579_RX_CONFIG;
+			else
+				emi_addr = I217_RX_CONFIG;
+			ret_val = e1000_write_emi_reg_locked(hw, emi_addr, 0);
 
 			hw->phy.ops.release(hw);
 
@@ -1147,15 +1523,17 @@
 
 	/* Work-around I218 hang issue */
 	if ((hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
-	    (hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
+	    (hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_I218_LM3) ||
+	    (hw->device_id == E1000_DEV_ID_PCH_I218_V3)) {
 		ret_val = e1000_k1_workaround_lpt_lp(hw, link);
 		if (ret_val)
 			return ret_val;
 	}
-
 	if (hw->mac.type == e1000_pch_lpt) {
-		/* Set platform power management values for Latency Tolerance
-		 * Reporting (LTR) and Optimized Buffer Flush/Fill (OBFF).
+		/* Set platform power management values for
+		 * Latency Tolerance Reporting (LTR)
+		 * Optimized Buffer Flush/Fill (OBFF)
 		 */
 		ret_val = e1000_platform_pm_pch_lpt(hw, link);
 		if (ret_val)
@@ -1207,9 +1585,11 @@
 	e1000_check_downshift_generic(hw);
 
 	/* Enable/Disable EEE after link up */
-	ret_val = e1000_set_eee_pchlan(hw);
-	if (ret_val)
-		return ret_val;
+	if (hw->phy.type > e1000_phy_82579) {
+		ret_val = e1000_set_eee_pchlan(hw);
+		if (ret_val)
+			return ret_val;
+	}
 
 	/* If we are forcing speed/duplex, then we simply return since
 	 * we have already determined whether we have link or not.
@@ -1433,7 +1813,7 @@
  *  contain the MAC address but RAR[1-6] are reserved for manageability (ME).
  *  Use SHRA[0-3] in place of those reserved for ME.
  **/
-static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
+static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
 {
 	u32 rar_low, rar_high;
 
@@ -1457,10 +1837,13 @@
 		E1000_WRITE_FLUSH(hw);
 		E1000_WRITE_REG(hw, E1000_RAH(index), rar_high);
 		E1000_WRITE_FLUSH(hw);
-		return;
+		return E1000_SUCCESS;
 	}
 
-	if (index < hw->mac.rar_entry_count) {
+	/* RAR[1-6] are owned by manageability.  Skip those and program the
+	 * next address into the SHRA register array.
+	 */
+	if (index < (u32) (hw->mac.rar_entry_count)) {
 		s32 ret_val;
 
 		ret_val = e1000_acquire_swflag_ich8lan(hw);
@@ -1477,7 +1860,7 @@
 		/* verify the register updates */
 		if ((E1000_READ_REG(hw, E1000_SHRAL(index - 1)) == rar_low) &&
 		    (E1000_READ_REG(hw, E1000_SHRAH(index - 1)) == rar_high))
-			return;
+			return E1000_SUCCESS;
 
 		DEBUGOUT2("SHRA[%d] might be locked by ME - FWSM=0x%8.8x\n",
 			 (index - 1), E1000_READ_REG(hw, E1000_FWSM));
@@ -1485,6 +1868,7 @@
 
 out:
 	DEBUGOUT1("Failed to write receive address at index %d\n", index);
+	return -E1000_ERR_CONFIG;
 }
 
 /**
@@ -1498,7 +1882,7 @@
  *  contain the MAC address. SHRA[0-10] are the shared receive address
  *  registers that are shared between the Host and manageability engine (ME).
  **/
-static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index)
+static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index)
 {
 	u32 rar_low, rar_high;
 	u32 wlock_mac;
@@ -1522,7 +1906,7 @@
 		E1000_WRITE_FLUSH(hw);
 		E1000_WRITE_REG(hw, E1000_RAH(index), rar_high);
 		E1000_WRITE_FLUSH(hw);
-		return;
+		return E1000_SUCCESS;
 	}
 
 	/* The manageability engine (ME) can lock certain SHRAR registers that
@@ -1557,12 +1941,13 @@
 			/* verify the register updates */
 			if ((E1000_READ_REG(hw, E1000_SHRAL_PCH_LPT(index - 1)) == rar_low) &&
 			    (E1000_READ_REG(hw, E1000_SHRAH_PCH_LPT(index - 1)) == rar_high))
-				return;
+				return E1000_SUCCESS;
 		}
 	}
 
 out:
 	DEBUGOUT1("Failed to write receive address at index %d\n", index);
+	return -E1000_ERR_CONFIG;
 }
 
 /**
@@ -1620,13 +2005,21 @@
 static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
 {
 	u32 fwsm;
+	bool blocked = FALSE;
+	int i = 0;
 
 	DEBUGFUNC("e1000_check_reset_block_ich8lan");
 
-	fwsm = E1000_READ_REG(hw, E1000_FWSM);
-
-	return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? E1000_SUCCESS
-						: E1000_BLK_PHY_RESET;
+	do {
+		fwsm = E1000_READ_REG(hw, E1000_FWSM);
+		if (!(fwsm & E1000_ICH_FWSM_RSPCIPHY)) {
+			blocked = TRUE;
+			msec_delay(10);
+			continue;
+		}
+		blocked = FALSE;
+	} while (blocked && (i++ < 10));
+	return blocked ? E1000_BLK_PHY_RESET : E1000_SUCCESS;
 }
 
 /**
@@ -1826,9 +2219,9 @@
 			if (ret_val)
 				goto release;
 
-			status_reg &= BM_CS_STATUS_LINK_UP |
-				      BM_CS_STATUS_RESOLVED |
-				      BM_CS_STATUS_SPEED_MASK;
+			status_reg &= (BM_CS_STATUS_LINK_UP |
+				       BM_CS_STATUS_RESOLVED |
+				       BM_CS_STATUS_SPEED_MASK);
 
 			if (status_reg == (BM_CS_STATUS_LINK_UP |
 					   BM_CS_STATUS_RESOLVED |
@@ -1842,9 +2235,9 @@
 			if (ret_val)
 				goto release;
 
-			status_reg &= HV_M_STATUS_LINK_UP |
-				      HV_M_STATUS_AUTONEG_COMPLETE |
-				      HV_M_STATUS_SPEED_MASK;
+			status_reg &= (HV_M_STATUS_LINK_UP |
+				       HV_M_STATUS_AUTONEG_COMPLETE |
+				       HV_M_STATUS_SPEED_MASK);
 
 			if (status_reg == (HV_M_STATUS_LINK_UP |
 					   HV_M_STATUS_AUTONEG_COMPLETE |
@@ -2126,8 +2519,8 @@
 	if (ret_val)
 		goto release;
 
-	/* Copy both RAL/H (rar_entry_count) and SHRAL/H (+4) to PHY */
-	for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
+	/* Copy both RAL/H (rar_entry_count) and SHRAL/H to PHY */
+	for (i = 0; i < (hw->mac.rar_entry_count); i++) {
 		mac_reg = E1000_READ_REG(hw, E1000_RAL(i));
 		hw->phy.ops.write_reg_page(hw, BM_RAR_L(i),
 					   (u16)(mac_reg & 0xFFFF));
@@ -2192,10 +2585,10 @@
 		return ret_val;
 
 	if (enable) {
-		/* Write Rx addresses (rar_entry_count for RAL/H, +4 for
+		/* Write Rx addresses (rar_entry_count for RAL/H, and
 		 * SHRAL/H) and initial CRC values to the MAC
 		 */
-		for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
+		for (i = 0; i < hw->mac.rar_entry_count; i++) {
 			u8 mac_addr[ETH_ADDR_LEN] = {0};
 			u32 addr_high, addr_low;
 
@@ -2264,7 +2657,7 @@
 			return ret_val;
 		hw->phy.ops.read_reg(hw, PHY_REG(776, 20), &data);
 		data &= ~(0x3FF << 2);
-		data |= (0x1A << 2);
+		data |= (E1000_TX_PTR_GAP << 2);
 		ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 20), data);
 		if (ret_val)
 			return ret_val;
@@ -2378,14 +2771,13 @@
  *  e1000_k1_gig_workaround_lv - K1 Si workaround
  *  @hw:   pointer to the HW structure
  *
- *  Workaround to set the K1 beacon duration for 82579 parts
+ *  Workaround to set the K1 beacon duration for 82579 parts in 10Mbps
+ *  Disable K1 for 1000 and 100 speeds
  **/
 static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
 {
 	s32 ret_val = E1000_SUCCESS;
 	u16 status_reg = 0;
-	u32 mac_reg;
-	u16 phy_reg;
 
 	DEBUGFUNC("e1000_k1_workaround_lv");
 
@@ -2392,7 +2784,7 @@
 	if (hw->mac.type != e1000_pch2lan)
 		return E1000_SUCCESS;
 
-	/* Set K1 beacon duration based on 1Gbps speed or otherwise */
+	/* Set K1 beacon duration based on 10Mbs speed */
 	ret_val = hw->phy.ops.read_reg(hw, HV_M_STATUS, &status_reg);
 	if (ret_val)
 		return ret_val;
@@ -2399,34 +2791,27 @@
 
 	if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
 	    == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
-		mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4);
-		mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
-
-		ret_val = hw->phy.ops.read_reg(hw, I82579_LPI_CTRL, &phy_reg);
-		if (ret_val)
-			return ret_val;
-
-		if (status_reg & HV_M_STATUS_SPEED_1000) {
+		if (status_reg &
+		    (HV_M_STATUS_SPEED_1000 | HV_M_STATUS_SPEED_100)) {
 			u16 pm_phy_reg;
 
-			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
-			phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
-			/* LV 1G Packet drop issue wa  */
+			/* LV 1G/100 Packet drop issue wa  */
 			ret_val = hw->phy.ops.read_reg(hw, HV_PM_CTRL,
 						       &pm_phy_reg);
 			if (ret_val)
 				return ret_val;
-			pm_phy_reg &= ~HV_PM_CTRL_PLL_STOP_IN_K1_GIGA;
+			pm_phy_reg &= ~HV_PM_CTRL_K1_ENABLE;
 			ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL,
 							pm_phy_reg);
 			if (ret_val)
 				return ret_val;
 		} else {
+			u32 mac_reg;
+			mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4);
+			mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
 			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
-			phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
+			E1000_WRITE_REG(hw, E1000_FEXTNVM4, mac_reg);
 		}
-		E1000_WRITE_REG(hw, E1000_FEXTNVM4, mac_reg);
-		ret_val = hw->phy.ops.write_reg(hw, I82579_LPI_CTRL, phy_reg);
 	}
 
 	return ret_val;
@@ -2963,7 +3348,6 @@
 	/* Clear FCERR and DAEL in hw status by writing 1 */
 	hsfsts.hsf_status.flcerr = 1;
 	hsfsts.hsf_status.dael = 1;
-
 	E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
 
 	/* Either we should have a hardware SPI cycle in progress
@@ -3030,6 +3414,7 @@
 	/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
 	hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
 	hsflctl.hsf_ctrl.flcgo = 1;
+
 	E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
 
 	/* wait till FDONE bit is set to 1 */
@@ -3084,6 +3469,7 @@
 	u16 word = 0;
 
 	ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word);
+
 	if (ret_val)
 		return ret_val;
 
@@ -3113,12 +3499,11 @@
 
 	DEBUGFUNC("e1000_read_flash_data_ich8lan");
 
-	if (size < 1  || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
+	if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
 		return -E1000_ERR_NVM;
+	flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
+			     hw->nvm.flash_base_addr);
 
-	flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
-			    hw->nvm.flash_base_addr;
-
 	do {
 		usec_delay(1);
 		/* Steps */
@@ -3125,13 +3510,12 @@
 		ret_val = e1000_flash_cycle_init_ich8lan(hw);
 		if (ret_val != E1000_SUCCESS)
 			break;
+		hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
 
-		hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
 		/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
 		hsflctl.hsf_ctrl.fldbcount = size - 1;
 		hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ;
 		E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
-
 		E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr);
 
 		ret_val = e1000_flash_cycle_ich8lan(hw,
@@ -3170,6 +3554,7 @@
 	return ret_val;
 }
 
+
 /**
  *  e1000_write_nvm_ich8lan - Write word(s) to the NVM
  *  @hw: pointer to the HW structure
@@ -3223,7 +3608,7 @@
 	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
 	u32 i, act_offset, new_bank_offset, old_bank_offset, bank;
 	s32 ret_val;
-	u16 data;
+	u16 data = 0;
 
 	DEBUGFUNC("e1000_update_nvm_checksum_ich8lan");
 
@@ -3259,12 +3644,7 @@
 		if (ret_val)
 			goto release;
 	}
-
 	for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
-		/* Determine whether to write the value stored
-		 * in the other NVM bank or a modified value stored
-		 * in the shadow RAM
-		 */
 		if (dev_spec->shadow_ram[i].modified) {
 			data = dev_spec->shadow_ram[i].value;
 		} else {
@@ -3274,7 +3654,6 @@
 			if (ret_val)
 				break;
 		}
-
 		/* If the word is 0x13, then make sure the signature bits
 		 * (15:14) are 11b until the commit has completed.
 		 * This will allow us to write 10b which indicates the
@@ -3289,6 +3668,7 @@
 		act_offset = (i + new_bank_offset) << 1;
 
 		usec_delay(100);
+
 		/* Write the bytes to the new bank. */
 		ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
 							       act_offset,
@@ -3302,7 +3682,7 @@
 							  (u8)(data >> 8));
 		if (ret_val)
 			break;
-	}
+	 }
 
 	/* Don't bother writing the segment valid bits if sector
 	 * programming failed.
@@ -3323,8 +3703,7 @@
 		goto release;
 
 	data &= 0xBFFF;
-	ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
-						       act_offset * 2 + 1,
+	ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset * 2 + 1,
 						       (u8)(data >> 8));
 	if (ret_val)
 		goto release;
@@ -3335,7 +3714,9 @@
 	 * to 1's. We can write 1's to 0's without an erase
 	 */
 	act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
+
 	ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
+
 	if (ret_val)
 		goto release;
 
@@ -3434,12 +3815,11 @@
 
 	DEBUGFUNC("e1000_write_ich8_data");
 
-	if (size < 1 || size > 2 || data > size * 0xff ||
-	    offset > ICH_FLASH_LINEAR_ADDR_MASK)
+	if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
 		return -E1000_ERR_NVM;
 
-	flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
-			    hw->nvm.flash_base_addr;
+	flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
+			     hw->nvm.flash_base_addr);
 
 	do {
 		usec_delay(1);
@@ -3447,8 +3827,8 @@
 		ret_val = e1000_flash_cycle_init_ich8lan(hw);
 		if (ret_val != E1000_SUCCESS)
 			break;
+		hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
 
-		hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
 		/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
 		hsflctl.hsf_ctrl.fldbcount = size - 1;
 		hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
@@ -3466,8 +3846,9 @@
 		/* check if FCERR is set to 1 , if set to 1, clear it
 		 * and try the whole sequence a few more times else done
 		 */
-		ret_val = e1000_flash_cycle_ich8lan(hw,
-					       ICH_FLASH_WRITE_COMMAND_TIMEOUT);
+		ret_val =
+		    e1000_flash_cycle_ich8lan(hw,
+					      ICH_FLASH_WRITE_COMMAND_TIMEOUT);
 		if (ret_val == E1000_SUCCESS)
 			break;
 
@@ -3489,6 +3870,7 @@
 	return ret_val;
 }
 
+
 /**
  *  e1000_write_flash_byte_ich8lan - Write a single byte to NVM
  *  @hw: pointer to the HW structure
@@ -3507,6 +3889,8 @@
 	return e1000_write_flash_data_ich8lan(hw, offset, 1, word);
 }
 
+
+
 /**
  *  e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM
  *  @hw: pointer to the HW structure
@@ -3603,8 +3987,10 @@
 	flash_linear_addr = hw->nvm.flash_base_addr;
 	flash_linear_addr += (bank) ? flash_bank_size : 0;
 
-	for (j = 0; j < iteration ; j++) {
+	for (j = 0; j < iteration; j++) {
 		do {
+			u32 timeout = ICH_FLASH_ERASE_COMMAND_TIMEOUT;
+
 			/* Steps */
 			ret_val = e1000_flash_cycle_init_ich8lan(hw);
 			if (ret_val)
@@ -3613,8 +3999,9 @@
 			/* Write a value 11 (block Erase) in Flash
 			 * Cycle field in hw flash control
 			 */
-			hsflctl.regval = E1000_READ_FLASH_REG16(hw,
-							      ICH_FLASH_HSFCTL);
+			hsflctl.regval =
+			    E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
+
 			hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
 			E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL,
 						hsflctl.regval);
@@ -3627,8 +4014,7 @@
 			E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR,
 					      flash_linear_addr);
 
-			ret_val = e1000_flash_cycle_ich8lan(hw,
-					       ICH_FLASH_ERASE_COMMAND_TIMEOUT);
+			ret_val = e1000_flash_cycle_ich8lan(hw, timeout);
 			if (ret_val == E1000_SUCCESS)
 				break;
 
@@ -3755,7 +4141,7 @@
  *  @hw: pointer to the HW structure
  *
  *  ICH8 use the PCI Express bus, but does not contain a PCI Express Capability
- *  register, so the bus width is hard coded.
+ *  register, so the the bus width is hard coded.
  **/
 static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
 {
@@ -3948,16 +4334,16 @@
 
 	/* Set the transmit descriptor write-back policy for both queues */
 	txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0));
-	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
-		 E1000_TXDCTL_FULL_TX_DESC_WB;
-	txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) |
-		 E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
+	txdctl = ((txdctl & ~E1000_TXDCTL_WTHRESH) |
+		  E1000_TXDCTL_FULL_TX_DESC_WB);
+	txdctl = ((txdctl & ~E1000_TXDCTL_PTHRESH) |
+		  E1000_TXDCTL_MAX_TX_DESC_PREFETCH);
 	E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl);
 	txdctl = E1000_READ_REG(hw, E1000_TXDCTL(1));
-	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
-		 E1000_TXDCTL_FULL_TX_DESC_WB;
-	txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) |
-		 E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
+	txdctl = ((txdctl & ~E1000_TXDCTL_WTHRESH) |
+		  E1000_TXDCTL_FULL_TX_DESC_WB);
+	txdctl = ((txdctl & ~E1000_TXDCTL_PTHRESH) |
+		  E1000_TXDCTL_MAX_TX_DESC_PREFETCH);
 	E1000_WRITE_REG(hw, E1000_TXDCTL(1), txdctl);
 
 	/* ICH8 has opposite polarity of no_snoop bits.
@@ -4042,6 +4428,7 @@
 	 */
 	reg = E1000_READ_REG(hw, E1000_RFCTL);
 	reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
+
 	/* Disable IPv6 extension header parsing because some malformed
 	 * IPv6 headers can hang the Rx.
 	 */
@@ -4480,7 +4867,9 @@
 		u16 phy_reg, device_id = hw->device_id;
 
 		if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
-		    (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
+		    (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) ||
+		    (device_id == E1000_DEV_ID_PCH_I218_LM3) ||
+		    (device_id == E1000_DEV_ID_PCH_I218_V3)) {
 			u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
 
 			E1000_WRITE_REG(hw, E1000_FEXTNVM6,
@@ -4503,14 +4892,25 @@
 
 			/* Disable LPLU if both link partners support 100BaseT
 			 * EEE and 100Full is advertised on both ends of the
-			 * link.
+			 * link, and enable Auto Enable LPI since there will
+			 * be no driver to enable LPI while in Sx.
 			 */
 			if ((eee_advert & I82579_EEE_100_SUPPORTED) &&
 			    (dev_spec->eee_lp_ability &
 			     I82579_EEE_100_SUPPORTED) &&
-			    (hw->phy.autoneg_advertised & ADVERTISE_100_FULL))
+			    (hw->phy.autoneg_advertised & ADVERTISE_100_FULL)) {
 				phy_ctrl &= ~(E1000_PHY_CTRL_D0A_LPLU |
 					      E1000_PHY_CTRL_NOND0A_LPLU);
+
+				/* Set Auto Enable LPI after link up */
+				hw->phy.ops.read_reg_locked(hw,
+							    I217_LPI_GPIO_CTRL,
+							    &phy_reg);
+				phy_reg |= I217_LPI_GPIO_CTRL_AUTO_EN_LPI;
+				hw->phy.ops.write_reg_locked(hw,
+							     I217_LPI_GPIO_CTRL,
+							     phy_reg);
+			}
 		}
 
 		/* For i217 Intel Rapid Start Technology support,
@@ -4521,7 +4921,7 @@
 		 * The SMBus release must also be disabled on LCD reset.
 		 */
 		if (!(E1000_READ_REG(hw, E1000_FWSM) &
-			E1000_ICH_FWSM_FW_VALID)) {
+		      E1000_ICH_FWSM_FW_VALID)) {
 			/* Enable proxy to reset only on power good. */
 			hw->phy.ops.read_reg_locked(hw, I217_PROXY_CTRL,
 						    &phy_reg);
@@ -4614,6 +5014,11 @@
 			return;
 		}
 
+		/* Clear Auto Enable LPI after link up */
+		hw->phy.ops.read_reg_locked(hw, I217_LPI_GPIO_CTRL, &phy_reg);
+		phy_reg &= ~I217_LPI_GPIO_CTRL_AUTO_EN_LPI;
+		hw->phy.ops.write_reg_locked(hw, I217_LPI_GPIO_CTRL, phy_reg);
+
 		if (!(E1000_READ_REG(hw, E1000_FWSM) &
 		    E1000_ICH_FWSM_FW_VALID)) {
 			/* Restore clear on SMB if no manageability engine

Modified: trunk/sys/dev/e1000/e1000_ich8lan.h
===================================================================
--- trunk/sys/dev/e1000/e1000_ich8lan.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_ich8lan.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_ich8lan.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_ich8lan.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_ICH8LAN_H_
 #define _E1000_ICH8LAN_H_
@@ -61,10 +60,10 @@
 #define ICH_FLASH_SEG_SIZE_8K		8192
 #define ICH_FLASH_SEG_SIZE_64K		65536
 
-#define E1000_ICH_FWSM_RSPCIPHY		0x00000040 /* Reset PHY on PCI Reset */
+#define E1000_ICH_FWSM_RSPCIPHY	0x00000040 /* Reset PHY on PCI Reset */
 /* FW established a valid mode */
-#define E1000_ICH_FWSM_FW_VALID		0x00008000
-#define E1000_ICH_FWSM_PCIM2PCI		0x01000000 /* ME PCIm-to-PCI active */
+#define E1000_ICH_FWSM_FW_VALID	0x00008000
+#define E1000_ICH_FWSM_PCIM2PCI	0x01000000 /* ME PCIm-to-PCI active */
 #define E1000_ICH_FWSM_PCIM2PCI_COUNT	2000
 
 #define E1000_ICH_MNG_IAMT_MODE		0x2
@@ -71,11 +70,16 @@
 
 #define E1000_FWSM_WLOCK_MAC_MASK	0x0380
 #define E1000_FWSM_WLOCK_MAC_SHIFT	7
+#define E1000_FWSM_ULP_CFG_DONE		0x00000400  /* Low power cfg done */
 
 /* Shared Receive Address Registers */
 #define E1000_SHRAL_PCH_LPT(_i)		(0x05408 + ((_i) * 8))
 #define E1000_SHRAH_PCH_LPT(_i)		(0x0540C + ((_i) * 8))
 
+#define E1000_H2ME		0x05B50    /* Host to ME */
+#define E1000_H2ME_ULP		0x00000800 /* ULP Indication Bit */
+#define E1000_H2ME_ENFORCE_SETTINGS	0x00001000 /* Enforce Settings */
+
 #define ID_LED_DEFAULT_ICH8LAN	((ID_LED_DEF1_DEF2 << 12) | \
 				 (ID_LED_OFF1_OFF2 <<  8) | \
 				 (ID_LED_OFF1_ON2  <<  4) | \
@@ -88,8 +92,11 @@
 
 #define E1000_ICH8_LAN_INIT_TIMEOUT	1500
 
+/* FEXT register bit definition */
+#define E1000_FEXT_PHY_CABLE_DISCONNECTED	0x00000004
+
 #define E1000_FEXTNVM_SW_CONFIG		1
-#define E1000_FEXTNVM_SW_CONFIG_ICH8M	(1 << 27) /* Bit redefined for ICH8M */
+#define E1000_FEXTNVM_SW_CONFIG_ICH8M	(1 << 27) /* different on ICH8M */
 
 #define E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK	0x0C000000
 #define E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC	0x08000000
@@ -99,7 +106,10 @@
 #define E1000_FEXTNVM4_BEACON_DURATION_16USEC	0x3
 
 #define E1000_FEXTNVM6_REQ_PLL_CLK	0x00000100
+#define E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION	0x00000200
 
+#define E1000_FEXTNVM7_DISABLE_SMB_PERST	0x00000020
+
 #define PCIE_ICH8_SNOOP_ALL	PCIE_NO_SNOOP_ALL
 
 #define E1000_ICH_RAR_ENTRIES	7
@@ -109,8 +119,8 @@
 #define PHY_PAGE_SHIFT		5
 #define PHY_REG(page, reg)	(((page) << PHY_PAGE_SHIFT) | \
 				 ((reg) & MAX_PHY_REG_ADDRESS))
-#define IGP3_KMRN_DIAG		PHY_REG(770, 19) /* KMRN Diagnostic */
-#define IGP3_VR_CTRL		PHY_REG(776, 18) /* Voltage Regulator Control */
+#define IGP3_KMRN_DIAG	PHY_REG(770, 19) /* KMRN Diagnostic */
+#define IGP3_VR_CTRL	PHY_REG(776, 18) /* Voltage Regulator Control */
 
 #define IGP3_KMRN_DIAG_PCS_LOCK_LOSS		0x0002
 #define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK	0x0300
@@ -141,19 +151,20 @@
 #define HV_MUX_DATA_CTRL_GEN_TO_MAC	0x0400
 #define HV_MUX_DATA_CTRL_FORCE_SPEED	0x0004
 #define HV_STATS_PAGE	778
-#define HV_SCC_UPPER	PHY_REG(HV_STATS_PAGE, 16) /* Single Collision Count */
+/* Half-duplex collision counts */
+#define HV_SCC_UPPER	PHY_REG(HV_STATS_PAGE, 16) /* Single Collision */
 #define HV_SCC_LOWER	PHY_REG(HV_STATS_PAGE, 17)
-#define HV_ECOL_UPPER	PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. Count */
+#define HV_ECOL_UPPER	PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. */
 #define HV_ECOL_LOWER	PHY_REG(HV_STATS_PAGE, 19)
-#define HV_MCC_UPPER	PHY_REG(HV_STATS_PAGE, 20) /* Multiple Coll. Count */
+#define HV_MCC_UPPER	PHY_REG(HV_STATS_PAGE, 20) /* Multiple Collision */
 #define HV_MCC_LOWER	PHY_REG(HV_STATS_PAGE, 21)
-#define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision Count */
+#define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision */
 #define HV_LATECOL_LOWER PHY_REG(HV_STATS_PAGE, 24)
-#define HV_COLC_UPPER	PHY_REG(HV_STATS_PAGE, 25) /* Collision Count */
+#define HV_COLC_UPPER	PHY_REG(HV_STATS_PAGE, 25) /* Collision */
 #define HV_COLC_LOWER	PHY_REG(HV_STATS_PAGE, 26)
 #define HV_DC_UPPER	PHY_REG(HV_STATS_PAGE, 27) /* Defer Count */
 #define HV_DC_LOWER	PHY_REG(HV_STATS_PAGE, 28)
-#define HV_TNCRS_UPPER	PHY_REG(HV_STATS_PAGE, 29) /* Transmit with no CRS */
+#define HV_TNCRS_UPPER	PHY_REG(HV_STATS_PAGE, 29) /* Tx with no CRS */
 #define HV_TNCRS_LOWER	PHY_REG(HV_STATS_PAGE, 30)
 
 #define E1000_FCRTV_PCH	0x05F40 /* PCH Flow Control Refresh Timer Value */
@@ -165,6 +176,16 @@
 #define CV_SMB_CTRL		PHY_REG(769, 23)
 #define CV_SMB_CTRL_FORCE_SMBUS	0x0001
 
+/* I218 Ultra Low Power Configuration 1 Register */
+#define I218_ULP_CONFIG1		PHY_REG(779, 16)
+#define I218_ULP_CONFIG1_START		0x0001 /* Start auto ULP config */
+#define I218_ULP_CONFIG1_IND		0x0004 /* Pwr up from ULP indication */
+#define I218_ULP_CONFIG1_STICKY_ULP	0x0010 /* Set sticky ULP mode */
+#define I218_ULP_CONFIG1_INBAND_EXIT	0x0020 /* Inband on ULP exit */
+#define I218_ULP_CONFIG1_WOL_HOST	0x0040 /* WoL Host on ULP exit */
+#define I218_ULP_CONFIG1_RESET_TO_SMBUS	0x0100 /* Reset to SMBus mode */
+#define I218_ULP_CONFIG1_DISABLE_SMB_PERST	0x1000 /* Disable on PERST# */
+
 /* SMBus Address Phy Register */
 #define HV_SMB_ADDR		PHY_REG(768, 26)
 #define HV_SMB_ADDR_MASK	0x007F
@@ -199,16 +220,29 @@
 /* PHY Power Management Control */
 #define HV_PM_CTRL		PHY_REG(770, 17)
 #define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA	0x100
+#define HV_PM_CTRL_K1_ENABLE		0x4000
 
 #define SW_FLAG_TIMEOUT		1000 /* SW Semaphore flag timeout in ms */
 
+/* Inband Control */
+#define I217_INBAND_CTRL				PHY_REG(770, 18)
+#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK	0x3F00
+#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT	8
+
+/* Low Power Idle GPIO Control */
+#define I217_LPI_GPIO_CTRL			PHY_REG(772, 18)
+#define I217_LPI_GPIO_CTRL_AUTO_EN_LPI		0x0800
+
 /* PHY Low Power Idle Control */
 #define I82579_LPI_CTRL				PHY_REG(772, 20)
 #define I82579_LPI_CTRL_100_ENABLE		0x2000
 #define I82579_LPI_CTRL_1000_ENABLE		0x4000
 #define I82579_LPI_CTRL_ENABLE_MASK		0x6000
-#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT	0x80
 
+/* 82579 DFT Control */
+#define I82579_DFT_CTRL			PHY_REG(769, 20)
+#define I82579_DFT_CTRL_GATE_PHY_RESET	0x0040 /* Gate PHY Reset on MAC Reset */
+
 /* Extended Management Interface (EMI) Registers */
 #define I82579_EMI_ADDR		0x10
 #define I82579_EMI_DATA		0x11
@@ -217,16 +251,19 @@
 #define I82577_MSE_THRESHOLD	0x0887 /* 82577 Mean Square Error Threshold */
 #define I82579_MSE_LINK_DOWN	0x2411 /* MSE count before dropping link */
 #define I82579_RX_CONFIG		0x3412 /* Receive configuration */
-#define I82579_EEE_PCS_STATUS		0x182D	/* IEEE MMD Register 3.1 >> 8 */
+#define I82579_LPI_PLL_SHUT		0x4412 /* LPI PLL Shut Enable */
+#define I82579_EEE_PCS_STATUS		0x182E	/* IEEE MMD Register 3.1 >> 8 */
 #define I82579_EEE_CAPABILITY		0x0410 /* IEEE MMD Register 3.20 */
 #define I82579_EEE_ADVERTISEMENT	0x040E /* IEEE MMD Register 7.60 */
 #define I82579_EEE_LP_ABILITY		0x040F /* IEEE MMD Register 7.61 */
-#define I82579_EEE_100_SUPPORTED	(1 << 1) /* 100BaseTx EEE supported */
-#define I82579_EEE_1000_SUPPORTED	(1 << 2) /* 1000BaseTx EEE supported */
+#define I82579_EEE_100_SUPPORTED	(1 << 1) /* 100BaseTx EEE */
+#define I82579_EEE_1000_SUPPORTED	(1 << 2) /* 1000BaseTx EEE */
+#define I82579_LPI_100_PLL_SHUT	(1 << 2) /* 100M LPI PLL Shut Enabled */
 #define I217_EEE_PCS_STATUS	0x9401   /* IEEE MMD Register 3.1 */
 #define I217_EEE_CAPABILITY	0x8000   /* IEEE MMD Register 3.20 */
 #define I217_EEE_ADVERTISEMENT	0x8001   /* IEEE MMD Register 7.60 */
 #define I217_EEE_LP_ABILITY	0x8002   /* IEEE MMD Register 7.61 */
+#define I217_RX_CONFIG		0xB20C /* Receive configuration */
 
 #define E1000_EEE_RX_LPI_RCVD	0x0400	/* Tx LP idle received */
 #define E1000_EEE_TX_LPI_RCVD	0x0800	/* Rx LP idle received */
@@ -275,4 +312,8 @@
 void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
 s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
 s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data);
+s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data);
+s32 e1000_set_eee_pchlan(struct e1000_hw *hw);
+s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx);
+s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force);
 #endif /* _E1000_ICH8LAN_H_ */

Modified: trunk/sys/dev/e1000/e1000_mac.c
===================================================================
--- trunk/sys/dev/e1000/e1000_mac.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_mac.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_mac.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_mac.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 #include "e1000_api.h"
 
@@ -38,7 +37,7 @@
 static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw);
 static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw);
 static void e1000_config_collision_dist_generic(struct e1000_hw *hw);
-static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
+static int e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
 
 /**
  *  e1000_init_mac_ops_generic - Initialize MAC function pointers
@@ -86,7 +85,7 @@
  *  e1000_null_ops_generic - No-op function, returns 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_ops_generic(struct e1000_hw *hw)
+s32 e1000_null_ops_generic(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	DEBUGFUNC("e1000_null_ops_generic");
 	return E1000_SUCCESS;
@@ -96,7 +95,7 @@
  *  e1000_null_mac_generic - No-op function, return void
  *  @hw: pointer to the HW structure
  **/
-void e1000_null_mac_generic(struct e1000_hw *hw)
+void e1000_null_mac_generic(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	DEBUGFUNC("e1000_null_mac_generic");
 	return;
@@ -106,7 +105,8 @@
  *  e1000_null_link_info - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d)
+s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw,
+			 u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
 {
 	DEBUGFUNC("e1000_null_link_info");
 	return E1000_SUCCESS;
@@ -116,7 +116,8 @@
  *  e1000_null_mng_mode - No-op function, return FALSE
  *  @hw: pointer to the HW structure
  **/
-bool e1000_null_mng_mode(struct e1000_hw *hw) {
+bool e1000_null_mng_mode(struct e1000_hw E1000_UNUSEDARG *hw)
+{
 	DEBUGFUNC("e1000_null_mng_mode");
 	return FALSE;
 }
@@ -125,7 +126,8 @@
  *  e1000_null_update_mc - No-op function, return void
  *  @hw: pointer to the HW structure
  **/
-void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a)
+void e1000_null_update_mc(struct e1000_hw E1000_UNUSEDARG *hw,
+			  u8 E1000_UNUSEDARG *h, u32 E1000_UNUSEDARG a)
 {
 	DEBUGFUNC("e1000_null_update_mc");
 	return;
@@ -135,7 +137,8 @@
  *  e1000_null_write_vfta - No-op function, return void
  *  @hw: pointer to the HW structure
  **/
-void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b)
+void e1000_null_write_vfta(struct e1000_hw E1000_UNUSEDARG *hw,
+			   u32 E1000_UNUSEDARG a, u32 E1000_UNUSEDARG b)
 {
 	DEBUGFUNC("e1000_null_write_vfta");
 	return;
@@ -142,13 +145,14 @@
 }
 
 /**
- *  e1000_null_rar_set - No-op function, return void
+ *  e1000_null_rar_set - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a)
+int e1000_null_rar_set(struct e1000_hw E1000_UNUSEDARG *hw,
+			u8 E1000_UNUSEDARG *h, u32 E1000_UNUSEDARG a)
 {
 	DEBUGFUNC("e1000_null_rar_set");
-	return;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -155,7 +159,8 @@
  *  e1000_null_set_obff_timer - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_set_obff_timer(struct e1000_hw *hw, u32 a)
+s32 e1000_null_set_obff_timer(struct e1000_hw E1000_UNUSEDARG *hw,
+			      u32 E1000_UNUSEDARG a)
 {
 	DEBUGFUNC("e1000_null_set_obff_timer");
 	return E1000_SUCCESS;
@@ -470,7 +475,7 @@
  *  Sets the receive address array register at index to the address passed
  *  in by addr.
  **/
-static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
+static int e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
 {
 	u32 rar_low, rar_high;
 
@@ -496,6 +501,8 @@
 	E1000_WRITE_FLUSH(hw);
 	E1000_WRITE_REG(hw, E1000_RAH(index), rar_high);
 	E1000_WRITE_FLUSH(hw);
+
+	return E1000_SUCCESS;
 }
 
 /**
@@ -941,6 +948,7 @@
 {
 	s32 ret_val;
 	u16 nvm_data;
+	u16 nvm_offset = 0;
 
 	DEBUGFUNC("e1000_set_default_fc_generic");
 
@@ -952,8 +960,19 @@
 	 * control setting, then the variable hw->fc will
 	 * be initialized based on a value in the EEPROM.
 	 */
-	ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
+	if (hw->mac.type == e1000_i350) {
+		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(hw->bus.func);
+		ret_val = hw->nvm.ops.read(hw,
+					   NVM_INIT_CONTROL2_REG +
+					   nvm_offset,
+					   1, &nvm_data);
+	} else {
+		ret_val = hw->nvm.ops.read(hw,
+					   NVM_INIT_CONTROL2_REG,
+					   1, &nvm_data);
+	}
 
+
 	if (ret_val) {
 		DEBUGOUT("NVM Read Error\n");
 		return ret_val;
@@ -1676,7 +1695,7 @@
  *  Sets the speed and duplex to gigabit full duplex (the only possible option)
  *  for fiber/serdes links.
  **/
-s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
+s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSEDARG *hw,
 						    u16 *speed, u16 *duplex)
 {
 	DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic");
@@ -2079,7 +2098,8 @@
 
 	while (timeout) {
 		if (!(E1000_READ_REG(hw, E1000_STATUS) &
-		      E1000_STATUS_GIO_MASTER_ENABLE))
+		      E1000_STATUS_GIO_MASTER_ENABLE) ||
+				E1000_REMOVED(hw->hw_addr))
 			break;
 		usec_delay(100);
 		timeout--;
@@ -2188,7 +2208,7 @@
  *  Validate the MDI/MDIx setting, allowing for auto-crossover during forced
  *  operation.
  **/
-s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw *hw)
+s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	DEBUGFUNC("e1000_validate_mdi_setting_crossover_generic");
 

Modified: trunk/sys/dev/e1000/e1000_mac.h
===================================================================
--- trunk/sys/dev/e1000/e1000_mac.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_mac.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,12 +30,15 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_mac.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_mac.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_MAC_H_
 #define _E1000_MAC_H_
 
 void e1000_init_mac_ops_generic(struct e1000_hw *hw);
+#ifndef E1000_REMOVED
+#define E1000_REMOVED(a) (0)
+#endif /* E1000_REMOVED */
 void e1000_null_mac_generic(struct e1000_hw *hw);
 s32  e1000_null_ops_generic(struct e1000_hw *hw);
 s32  e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
@@ -43,7 +45,7 @@
 bool e1000_null_mng_mode(struct e1000_hw *hw);
 void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);
 void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
-void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a);
+int  e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a);
 s32  e1000_null_set_obff_timer(struct e1000_hw *hw, u32 a);
 s32  e1000_blink_led_generic(struct e1000_hw *hw);
 s32  e1000_check_for_copper_link_generic(struct e1000_hw *hw);

Modified: trunk/sys/dev/e1000/e1000_manage.c
===================================================================
--- trunk/sys/dev/e1000/e1000_manage.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_manage.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_manage.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_manage.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 #include "e1000_api.h"
 
@@ -365,9 +364,12 @@
 	} else if ((hw->mac.type == e1000_82574) ||
 		   (hw->mac.type == e1000_82583)) {
 		u16 data;
+		s32 ret_val;
 
 		factps = E1000_READ_REG(hw, E1000_FACTPS);
-		e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+		ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+		if (ret_val)
+			return FALSE;
 
 		if (!(factps & E1000_FACTPS_MNGCG) &&
 		    ((data & E1000_NVM_INIT_CTRL2_MNGM) ==
@@ -375,7 +377,7 @@
 			return TRUE;
 	} else if ((manc & E1000_MANC_SMBUS_EN) &&
 		   !(manc & E1000_MANC_ASF_EN)) {
-			return TRUE;
+		return TRUE;
 	}
 
 	return FALSE;

Modified: trunk/sys/dev/e1000/e1000_manage.h
===================================================================
--- trunk/sys/dev/e1000/e1000_manage.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_manage.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2012, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_manage.h 238262 2012-07-08 20:35:56Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_manage.h 238262 2012-07-08 20:35:56Z jfv $*/
 
 #ifndef _E1000_MANAGE_H_
 #define _E1000_MANAGE_H_

Modified: trunk/sys/dev/e1000/e1000_mbx.c
===================================================================
--- trunk/sys/dev/e1000/e1000_mbx.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_mbx.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2010, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_mbx.c 218530 2011-02-11 01:00:26Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_mbx.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 #include "e1000_mbx.h"
 
@@ -39,7 +38,8 @@
  *  e1000_null_mbx_check_for_flag - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-static s32 e1000_null_mbx_check_for_flag(struct e1000_hw *hw, u16 mbx_id)
+static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw,
+					 u16 E1000_UNUSEDARG mbx_id)
 {
 	DEBUGFUNC("e1000_null_mbx_check_flag");
 
@@ -50,8 +50,10 @@
  *  e1000_null_mbx_transact - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-static s32 e1000_null_mbx_transact(struct e1000_hw *hw, u32 *msg, u16 size,
-                            u16 mbx_id)
+static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw,
+				   u32 E1000_UNUSEDARG *msg,
+				   u16 E1000_UNUSEDARG size,
+				   u16 E1000_UNUSEDARG mbx_id)
 {
 	DEBUGFUNC("e1000_null_mbx_rw_msg");
 
@@ -355,7 +357,8 @@
  *
  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
  **/
-static s32 e1000_check_for_msg_vf(struct e1000_hw *hw, u16 mbx_id)
+static s32 e1000_check_for_msg_vf(struct e1000_hw *hw,
+				  u16 E1000_UNUSEDARG mbx_id)
 {
 	s32 ret_val = -E1000_ERR_MBX;
 
@@ -376,7 +379,8 @@
  *
  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
  **/
-static s32 e1000_check_for_ack_vf(struct e1000_hw *hw, u16 mbx_id)
+static s32 e1000_check_for_ack_vf(struct e1000_hw *hw,
+				  u16 E1000_UNUSEDARG mbx_id)
 {
 	s32 ret_val = -E1000_ERR_MBX;
 
@@ -397,7 +401,8 @@
  *
  *  returns TRUE if the PF has set the reset done bit or else FALSE
  **/
-static s32 e1000_check_for_rst_vf(struct e1000_hw *hw, u16 mbx_id)
+static s32 e1000_check_for_rst_vf(struct e1000_hw *hw,
+				  u16 E1000_UNUSEDARG mbx_id)
 {
 	s32 ret_val = -E1000_ERR_MBX;
 
@@ -404,7 +409,7 @@
 	DEBUGFUNC("e1000_check_for_rst_vf");
 
 	if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
-	                                 E1000_V2PMAILBOX_RSTI))) {
+					 E1000_V2PMAILBOX_RSTI))) {
 		ret_val = E1000_SUCCESS;
 		hw->mbx.stats.rsts++;
 	}
@@ -444,7 +449,7 @@
  *  returns SUCCESS if it successfully copied message into the buffer
  **/
 static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
-                              u16 mbx_id)
+			      u16 E1000_UNUSEDARG mbx_id)
 {
 	s32 ret_val;
 	u16 i;
@@ -485,7 +490,7 @@
  *  returns SUCCESS if it successfuly read message from buffer
  **/
 static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
-                             u16 mbx_id)
+			     u16 E1000_UNUSEDARG mbx_id)
 {
 	s32 ret_val = E1000_SUCCESS;
 	u16 i;
@@ -658,7 +663,7 @@
  *  returns SUCCESS if it successfully copied message into the buffer
  **/
 static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
-                              u16 vf_number)
+			      u16 vf_number)
 {
 	s32 ret_val;
 	u16 i;
@@ -701,7 +706,7 @@
  *  a message due to a VF request so no polling for message is needed.
  **/
 static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
-                             u16 vf_number)
+			     u16 vf_number)
 {
 	s32 ret_val;
 	u16 i;
@@ -740,6 +745,7 @@
 	switch (hw->mac.type) {
 	case e1000_82576:
 	case e1000_i350:
+	case e1000_i354:
 		mbx->timeout = 0;
 		mbx->usec_delay = 0;
 

Modified: trunk/sys/dev/e1000/e1000_mbx.h
===================================================================
--- trunk/sys/dev/e1000/e1000_mbx.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_mbx.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2010, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_mbx.h 209616 2010-06-30 21:05:51Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_mbx.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_MBX_H_
 #define _E1000_MBX_H_
@@ -39,59 +38,59 @@
 #include "e1000_api.h"
 
 /* Define mailbox register bits */
-#define E1000_V2PMAILBOX_REQ   0x00000001 /* Request for PF Ready bit */
-#define E1000_V2PMAILBOX_ACK   0x00000002 /* Ack PF message received */
-#define E1000_V2PMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */
-#define E1000_V2PMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */
-#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */
-#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */
-#define E1000_V2PMAILBOX_RSTI  0x00000040 /* PF has reset indication */
-#define E1000_V2PMAILBOX_RSTD  0x00000080 /* PF has indicated reset done */
+#define E1000_V2PMAILBOX_REQ	0x00000001 /* Request for PF Ready bit */
+#define E1000_V2PMAILBOX_ACK	0x00000002 /* Ack PF message received */
+#define E1000_V2PMAILBOX_VFU	0x00000004 /* VF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFU	0x00000008 /* PF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFSTS	0x00000010 /* PF wrote a message in the MB */
+#define E1000_V2PMAILBOX_PFACK	0x00000020 /* PF ack the previous VF msg */
+#define E1000_V2PMAILBOX_RSTI	0x00000040 /* PF has reset indication */
+#define E1000_V2PMAILBOX_RSTD	0x00000080 /* PF has indicated reset done */
 #define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */
 
-#define E1000_P2VMAILBOX_STS   0x00000001 /* Initiate message send to VF */
-#define E1000_P2VMAILBOX_ACK   0x00000002 /* Ack message recv'd from VF */
-#define E1000_P2VMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */
-#define E1000_P2VMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */
-#define E1000_P2VMAILBOX_RVFU  0x00000010 /* Reset VFU - used when VF stuck */
+#define E1000_P2VMAILBOX_STS	0x00000001 /* Initiate message send to VF */
+#define E1000_P2VMAILBOX_ACK	0x00000002 /* Ack message recv'd from VF */
+#define E1000_P2VMAILBOX_VFU	0x00000004 /* VF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_PFU	0x00000008 /* PF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_RVFU	0x00000010 /* Reset VFU - used when VF stuck */
 
 #define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
-#define E1000_MBVFICR_VFREQ_VF1  0x00000001 /* bit for VF 1 message */
+#define E1000_MBVFICR_VFREQ_VF1	0x00000001 /* bit for VF 1 message */
 #define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
-#define E1000_MBVFICR_VFACK_VF1  0x00010000 /* bit for VF 1 ack */
+#define E1000_MBVFICR_VFACK_VF1	0x00010000 /* bit for VF 1 ack */
 
-#define E1000_VFMAILBOX_SIZE   16 /* 16 32 bit words - 64 bytes */
+#define E1000_VFMAILBOX_SIZE	16 /* 16 32 bit words - 64 bytes */
 
 /* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
  * PF.  The reverse is TRUE if it is E1000_PF_*.
  * Message ACK's are the value or'd with 0xF0000000
  */
-#define E1000_VT_MSGTYPE_ACK      0x80000000  /* Messages below or'd with
-                                               * this are the ACK */
-#define E1000_VT_MSGTYPE_NACK     0x40000000  /* Messages below or'd with
-                                               * this are the NACK */
-#define E1000_VT_MSGTYPE_CTS      0x20000000  /* Indicates that VF is still
-                                                 clear to send requests */
-#define E1000_VT_MSGINFO_SHIFT    16
-/* bits 23:16 are used for exra info for certain messages */
-#define E1000_VT_MSGINFO_MASK     (0xFF << E1000_VT_MSGINFO_SHIFT)
+/* Msgs below or'd with this are the ACK */
+#define E1000_VT_MSGTYPE_ACK	0x80000000
+/* Msgs below or'd with this are the NACK */
+#define E1000_VT_MSGTYPE_NACK	0x40000000
+/* Indicates that VF is still clear to send requests */
+#define E1000_VT_MSGTYPE_CTS	0x20000000
+#define E1000_VT_MSGINFO_SHIFT	16
+/* bits 23:16 are used for extra info for certain messages */
+#define E1000_VT_MSGINFO_MASK	(0xFF << E1000_VT_MSGINFO_SHIFT)
 
-#define E1000_VF_RESET            0x01 /* VF requests reset */
-#define E1000_VF_SET_MAC_ADDR     0x02 /* VF requests to set MAC addr */
-#define E1000_VF_SET_MULTICAST    0x03 /* VF requests to set MC addr */
+#define E1000_VF_RESET			0x01 /* VF requests reset */
+#define E1000_VF_SET_MAC_ADDR		0x02 /* VF requests to set MAC addr */
+#define E1000_VF_SET_MULTICAST		0x03 /* VF requests to set MC addr */
 #define E1000_VF_SET_MULTICAST_COUNT_MASK (0x1F << E1000_VT_MSGINFO_SHIFT)
-#define E1000_VF_SET_MULTICAST_OVERFLOW   (0x80 << E1000_VT_MSGINFO_SHIFT)
-#define E1000_VF_SET_VLAN         0x04 /* VF requests to set VLAN */
-#define E1000_VF_SET_VLAN_ADD             (0x01 << E1000_VT_MSGINFO_SHIFT)
-#define E1000_VF_SET_LPE          0x05 /* VF requests to set VMOLR.LPE */
-#define E1000_VF_SET_PROMISC      0x06 /*VF requests to clear VMOLR.ROPE/MPME*/
-#define E1000_VF_SET_PROMISC_UNICAST      (0x01 << E1000_VT_MSGINFO_SHIFT)
-#define E1000_VF_SET_PROMISC_MULTICAST    (0x02 << E1000_VT_MSGINFO_SHIFT)
+#define E1000_VF_SET_MULTICAST_OVERFLOW	(0x80 << E1000_VT_MSGINFO_SHIFT)
+#define E1000_VF_SET_VLAN		0x04 /* VF requests to set VLAN */
+#define E1000_VF_SET_VLAN_ADD		(0x01 << E1000_VT_MSGINFO_SHIFT)
+#define E1000_VF_SET_LPE		0x05 /* reqs to set VMOLR.LPE */
+#define E1000_VF_SET_PROMISC		0x06 /* reqs to clear VMOLR.ROPE/MPME*/
+#define E1000_VF_SET_PROMISC_UNICAST	(0x01 << E1000_VT_MSGINFO_SHIFT)
+#define E1000_VF_SET_PROMISC_MULTICAST	(0x02 << E1000_VT_MSGINFO_SHIFT)
 
-#define E1000_PF_CONTROL_MSG      0x0100 /* PF control message */
+#define E1000_PF_CONTROL_MSG		0x0100 /* PF control message */
 
-#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
-#define E1000_VF_MBX_INIT_DELAY   500  /* microseconds between retries */
+#define E1000_VF_MBX_INIT_TIMEOUT	2000 /* number of retries on mailbox */
+#define E1000_VF_MBX_INIT_DELAY		500  /* microseconds between retries */
 
 s32 e1000_read_mbx(struct e1000_hw *, u32 *, u16, u16);
 s32 e1000_write_mbx(struct e1000_hw *, u32 *, u16, u16);

Modified: trunk/sys/dev/e1000/e1000_nvm.c
===================================================================
--- trunk/sys/dev/e1000/e1000_nvm.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_nvm.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_nvm.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_nvm.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 #include "e1000_api.h"
 
@@ -64,7 +63,9 @@
  *  e1000_null_nvm_read - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
+s32 e1000_null_read_nvm(struct e1000_hw E1000_UNUSEDARG *hw,
+			u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b,
+			u16 E1000_UNUSEDARG *c)
 {
 	DEBUGFUNC("e1000_null_read_nvm");
 	return E1000_SUCCESS;
@@ -74,7 +75,7 @@
  *  e1000_null_nvm_generic - No-op function, return void
  *  @hw: pointer to the HW structure
  **/
-void e1000_null_nvm_generic(struct e1000_hw *hw)
+void e1000_null_nvm_generic(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	DEBUGFUNC("e1000_null_nvm_generic");
 	return;
@@ -84,7 +85,8 @@
  *  e1000_null_led_default - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data)
+s32 e1000_null_led_default(struct e1000_hw E1000_UNUSEDARG *hw,
+			   u16 E1000_UNUSEDARG *data)
 {
 	DEBUGFUNC("e1000_null_led_default");
 	return E1000_SUCCESS;
@@ -94,7 +96,9 @@
  *  e1000_null_write_nvm - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
+s32 e1000_null_write_nvm(struct e1000_hw E1000_UNUSEDARG *hw,
+			 u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b,
+			 u16 E1000_UNUSEDARG *c)
 {
 	DEBUGFUNC("e1000_null_write_nvm");
 	return E1000_SUCCESS;
@@ -578,6 +582,9 @@
 			   E1000_NVM_RW_REG_DATA);
 	}
 
+	if (ret_val)
+		DEBUGOUT1("NVM read error: %d\n", ret_val);
+
 	return ret_val;
 }
 
@@ -768,6 +775,12 @@
 
 	DEBUGFUNC("e1000_read_pba_string_generic");
 
+	if ((hw->mac.type >= e1000_i210) &&
+	    !e1000_get_flash_presence_i210(hw)) {
+		DEBUGOUT("Flashless no PBA string\n");
+		return -E1000_ERR_NVM_PBA_SECTION;
+	}
+
 	if (pba_num == NULL) {
 		DEBUGOUT("PBA string buffer was null\n");
 		return -E1000_ERR_INVALID_ARGUMENT;
@@ -975,7 +988,7 @@
 				return ret_val;
 		} else {
 			if (eeprom_buf_size > (u32)(pba->word[1] +
-					      pba->pba_block[0])) {
+					      pba_block_size)) {
 				memcpy(pba->pba_block,
 				       &eeprom_buf[pba->word[1]],
 				       pba_block_size * sizeof(u16));

Modified: trunk/sys/dev/e1000/e1000_nvm.h
===================================================================
--- trunk/sys/dev/e1000/e1000_nvm.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_nvm.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2013, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_nvm.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_nvm.h 248292 2013-03-14 22:55:59Z jfv $*/
 
 #ifndef _E1000_NVM_H_
 #define _E1000_NVM_H_

Modified: trunk/sys/dev/e1000/e1000_osdep.c
===================================================================
--- trunk/sys/dev/e1000/e1000_osdep.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_osdep.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2010, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_osdep.c 219902 2011-03-23 13:10:15Z jhb $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_osdep.c 219902 2011-03-23 13:10:15Z jhb $*/
 
 #include "e1000_api.h"
 

Modified: trunk/sys/dev/e1000/e1000_osdep.h
===================================================================
--- trunk/sys/dev/e1000/e1000_osdep.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_osdep.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_osdep.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_osdep.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 
 #ifndef _FREEBSD_OS_H_
@@ -61,14 +60,13 @@
 #define ASSERT(x) if(!(x)) panic("EM: x")
 
 #define usec_delay(x) DELAY(x)
+#define usec_delay_irq(x) DELAY(x)
 #define msec_delay(x) DELAY(1000*(x))
 #define msec_delay_irq(x) DELAY(1000*(x))
 
-#define MSGOUT(S, A, B)     printf(S "\n", A, B)
 #define DEBUGFUNC(F)        DEBUGOUT(F);
 #define DEBUGOUT(S)			do {} while (0)
-/* This define is needed or shared code will not build */
-#define DEBUGOUT1(S,A)			if (0) printf(S,A);
+#define DEBUGOUT1(S,A)			do {} while (0)
 #define DEBUGOUT2(S,A,B)		do {} while (0)
 #define DEBUGOUT3(S,A,B,C)		do {} while (0)
 #define DEBUGOUT7(S,A,B,C,D,E,F,G)	do {} while (0)
@@ -77,7 +75,7 @@
 #define FALSE			0
 #define TRUE			1
 #ifndef __bool_true_false_are_defined
-#define false			FALSE
+#define false			FALSE 
 #define true			TRUE
 #endif
 #define CMD_MEM_WRT_INVALIDATE	0x0010  /* BIT_4 */
@@ -87,7 +85,7 @@
 #define E1000_MUTEX                     struct mtx
 #define E1000_MUTEX_INIT(mutex)         mtx_init((mutex), #mutex, \
                                             MTX_NETWORK_LOCK, \
-                                            MTX_DEF | MTX_DUPOK)
+					    MTX_DEF | MTX_DUPOK)
 #define E1000_MUTEX_DESTROY(mutex)      mtx_destroy(mutex)
 #define E1000_MUTEX_LOCK(mutex)         mtx_lock(mutex)
 #define E1000_MUTEX_TRYLOCK(mutex)      mtx_trylock(mutex)
@@ -109,7 +107,7 @@
 #define __le32		u32
 #define __le64		u64
 
-#if __FreeBSD_version < 800000 /* Now in HEAD */
+#if __FreeBSD_version < 800000
 #if defined(__i386__) || defined(__amd64__)
 #define mb()	__asm volatile("mfence" ::: "memory")
 #define wmb()	__asm volatile("sfence" ::: "memory")

Modified: trunk/sys/dev/e1000/e1000_phy.c
===================================================================
--- trunk/sys/dev/e1000/e1000_phy.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_phy.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_phy.c 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_phy.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 #include "e1000_api.h"
 
@@ -105,7 +104,8 @@
  *  e1000_null_set_page - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_set_page(struct e1000_hw *hw, u16 data)
+s32 e1000_null_set_page(struct e1000_hw E1000_UNUSEDARG *hw,
+			u16 E1000_UNUSEDARG data)
 {
 	DEBUGFUNC("e1000_null_set_page");
 	return E1000_SUCCESS;
@@ -115,7 +115,8 @@
  *  e1000_null_read_reg - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data)
+s32 e1000_null_read_reg(struct e1000_hw E1000_UNUSEDARG *hw,
+			u32 E1000_UNUSEDARG offset, u16 E1000_UNUSEDARG *data)
 {
 	DEBUGFUNC("e1000_null_read_reg");
 	return E1000_SUCCESS;
@@ -125,7 +126,7 @@
  *  e1000_null_phy_generic - No-op function, return void
  *  @hw: pointer to the HW structure
  **/
-void e1000_null_phy_generic(struct e1000_hw *hw)
+void e1000_null_phy_generic(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	DEBUGFUNC("e1000_null_phy_generic");
 	return;
@@ -135,7 +136,8 @@
  *  e1000_null_lplu_state - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active)
+s32 e1000_null_lplu_state(struct e1000_hw E1000_UNUSEDARG *hw,
+			  bool E1000_UNUSEDARG active)
 {
 	DEBUGFUNC("e1000_null_lplu_state");
 	return E1000_SUCCESS;
@@ -145,7 +147,8 @@
  *  e1000_null_write_reg - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data)
+s32 e1000_null_write_reg(struct e1000_hw E1000_UNUSEDARG *hw,
+			 u32 E1000_UNUSEDARG offset, u16 E1000_UNUSEDARG data)
 {
 	DEBUGFUNC("e1000_null_write_reg");
 	return E1000_SUCCESS;
@@ -159,8 +162,10 @@
  *  @data: data value read
  *
  **/
-s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
-			     u8 dev_addr, u8 *data)
+s32 e1000_read_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG *hw,
+			     u8 E1000_UNUSEDARG byte_offset,
+			     u8 E1000_UNUSEDARG dev_addr,
+			     u8 E1000_UNUSEDARG *data)
 {
 	DEBUGFUNC("e1000_read_i2c_byte_null");
 	return E1000_SUCCESS;
@@ -174,10 +179,10 @@
  *  @data: data value to write
  *
  **/
-s32 e1000_write_i2c_byte_null(struct e1000_hw *hw,
-			      u8 byte_offset,
-			      u8 dev_addr,
-			      u8 data)
+s32 e1000_write_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG *hw,
+			      u8 E1000_UNUSEDARG byte_offset,
+			      u8 E1000_UNUSEDARG dev_addr,
+			      u8 E1000_UNUSEDARG data)
 {
 	DEBUGFUNC("e1000_write_i2c_byte_null");
 	return E1000_SUCCESS;
@@ -303,7 +308,7 @@
 	 * the lower time out
 	 */
 	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
-		usec_delay(50);
+		usec_delay_irq(50);
 		mdic = E1000_READ_REG(hw, E1000_MDIC);
 		if (mdic & E1000_MDIC_READY)
 			break;
@@ -328,7 +333,7 @@
 	 * reading duplicate data in the next MDIC transaction.
 	 */
 	if (hw->mac.type == e1000_pch2lan)
-		usec_delay(100);
+		usec_delay_irq(100);
 
 	return E1000_SUCCESS;
 }
@@ -369,7 +374,7 @@
 	 * the lower time out
 	 */
 	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
-		usec_delay(50);
+		usec_delay_irq(50);
 		mdic = E1000_READ_REG(hw, E1000_MDIC);
 		if (mdic & E1000_MDIC_READY)
 			break;
@@ -393,7 +398,7 @@
 	 * reading duplicate data in the next MDIC transaction.
 	 */
 	if (hw->mac.type == e1000_pch2lan)
-		usec_delay(100);
+		usec_delay_irq(100);
 
 	return E1000_SUCCESS;
 }
@@ -1055,16 +1060,12 @@
 		}
 	}
 
-	/* Enable CRS on Tx. This must be set for half-duplex operation.
-	 * Not required on some PHYs.
-	 */
+	/* Enable CRS on Tx. This must be set for half-duplex operation. */
 	ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data);
 	if (ret_val)
 		return ret_val;
 
-	if ((hw->phy.type != e1000_phy_82579) &&
-	    (hw->phy.type != e1000_phy_i217))
-		phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
+	phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
 
 	/* Enable downshift */
 	phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
@@ -1250,12 +1251,6 @@
 			return ret_val;
 	}
 
-	if (phy->type == e1000_phy_i210) {
-		ret_val = e1000_set_master_slave_mode(hw);
-		if (ret_val)
-			return ret_val;
-	}
-
 	return E1000_SUCCESS;
 }
 
@@ -1319,6 +1314,20 @@
 		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
 
 	/* Enable downshift and setting it to X6 */
+	if (phy->id == M88E1543_E_PHY_ID) {
+		phy_data &= ~I347AT4_PSCR_DOWNSHIFT_ENABLE;
+		ret_val =
+		    phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+		if (ret_val)
+			return ret_val;
+
+		ret_val = phy->ops.commit(hw);
+		if (ret_val) {
+			DEBUGOUT("Error committing the PHY changes\n");
+			return ret_val;
+		}
+	}
+
 	phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
 	phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
 	phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
@@ -1334,6 +1343,10 @@
 		return ret_val;
 	}
 
+	ret_val = e1000_set_master_slave_mode(hw);
+	if (ret_val)
+		return ret_val;
+
 	return E1000_SUCCESS;
 }
 
@@ -1848,6 +1861,8 @@
 			case I347AT4_E_PHY_ID:
 			case M88E1340M_E_PHY_ID:
 			case M88E1112_E_PHY_ID:
+			case M88E1543_E_PHY_ID:
+			case M88E1512_E_PHY_ID:
 			case I210_I_PHY_ID:
 				reset_dsp = FALSE;
 				break;
@@ -1890,6 +1905,9 @@
 		return E1000_SUCCESS;
 	if (hw->phy.id == I210_I_PHY_ID)
 		return E1000_SUCCESS;
+	if ((hw->phy.id == M88E1543_E_PHY_ID) ||
+	    (hw->phy.id == M88E1512_E_PHY_ID))
+		return E1000_SUCCESS;
 	ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		return ret_val;
@@ -2195,9 +2213,9 @@
 	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
 
 	if (!ret_val)
-		phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
-				      ? e1000_rev_polarity_reversed
-				      : e1000_rev_polarity_normal;
+		phy->cable_polarity = ((data & M88E1000_PSSR_REV_POLARITY)
+				       ? e1000_rev_polarity_reversed
+				       : e1000_rev_polarity_normal);
 
 	return ret_val;
 }
@@ -2241,9 +2259,9 @@
 	ret_val = phy->ops.read_reg(hw, offset, &data);
 
 	if (!ret_val)
-		phy->cable_polarity = (data & mask)
-				      ? e1000_rev_polarity_reversed
-				      : e1000_rev_polarity_normal;
+		phy->cable_polarity = ((data & mask)
+				       ? e1000_rev_polarity_reversed
+				       : e1000_rev_polarity_normal);
 
 	return ret_val;
 }
@@ -2275,9 +2293,9 @@
 	ret_val = phy->ops.read_reg(hw, offset, &phy_data);
 
 	if (!ret_val)
-		phy->cable_polarity = (phy_data & mask)
+		phy->cable_polarity = ((phy_data & mask)
 				       ? e1000_rev_polarity_reversed
-				       : e1000_rev_polarity_normal;
+				       : e1000_rev_polarity_normal);
 
 	return ret_val;
 }
@@ -2344,12 +2362,16 @@
 		 * it across the board.
 		 */
 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
-		if (ret_val)
+		if (ret_val) {
 			/* If the first read fails, another entity may have
 			 * ownership of the resources, wait and try again to
 			 * see if they have relinquished the resources yet.
 			 */
-			usec_delay(usec_interval);
+			if (usec_interval >= 1000)
+				msec_delay(usec_interval/1000);
+			else
+				usec_delay(usec_interval);
+		}
 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
 		if (ret_val)
 			break;
@@ -2356,7 +2378,7 @@
 		if (phy_status & MII_SR_LINK_STATUS)
 			break;
 		if (usec_interval >= 1000)
-			msec_delay_irq(usec_interval/1000);
+			msec_delay(usec_interval/1000);
 		else
 			usec_delay(usec_interval);
 	}
@@ -2393,8 +2415,8 @@
 	if (ret_val)
 		return ret_val;
 
-	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-		M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+	index = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+		 M88E1000_PSSR_CABLE_LENGTH_SHIFT);
 
 	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1)
 		return -E1000_ERR_PHY;
@@ -2438,6 +2460,8 @@
 		phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
 		phy->cable_length = phy_data / (is_cm ? 100 : 1);
 		break;
+	case M88E1543_E_PHY_ID:
+	case M88E1512_E_PHY_ID:
 	case M88E1340M_E_PHY_ID:
 	case I347AT4_E_PHY_ID:
 		/* Remember the original page select and set it to 7 */
@@ -2555,8 +2579,8 @@
 		 * that can be put into the lookup table to obtain the
 		 * approximate cable length.
 		 */
-		cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
-				IGP02E1000_AGC_LENGTH_MASK;
+		cur_agc_index = ((phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
+				 IGP02E1000_AGC_LENGTH_MASK);
 
 		/* Array index bound check. */
 		if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
@@ -2579,8 +2603,8 @@
 	agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
 
 	/* Calculate cable length with the error range of +/- 10 meters. */
-	phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
-				 (agc_value - IGP02E1000_AGC_RANGE) : 0;
+	phy->min_cable_length = (((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
+				 (agc_value - IGP02E1000_AGC_RANGE) : 0);
 	phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
@@ -2764,9 +2788,9 @@
 			return ret_val;
 	} else {
 		/* Polarity is forced */
-		phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
-				      ? e1000_rev_polarity_reversed
-				      : e1000_rev_polarity_normal;
+		phy->cable_polarity = ((data & IFE_PSC_FORCE_POLARITY)
+				       ? e1000_rev_polarity_reversed
+				       : e1000_rev_polarity_normal);
 	}
 
 	ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
@@ -2864,7 +2888,7 @@
  *  Generic function to wait 10 milli-seconds for configuration to complete
  *  and return success.
  **/
-s32 e1000_get_cfg_done_generic(struct e1000_hw *hw)
+s32 e1000_get_cfg_done_generic(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	DEBUGFUNC("e1000_get_cfg_done_generic");
 
@@ -2971,6 +2995,8 @@
 	case M88E1000_E_PHY_ID:
 	case M88E1111_I_PHY_ID:
 	case M88E1011_I_PHY_ID:
+	case M88E1543_E_PHY_ID:
+	case M88E1512_E_PHY_ID:
 	case I347AT4_E_PHY_ID:
 	case M88E1112_E_PHY_ID:
 	case M88E1340M_E_PHY_ID:
@@ -3403,11 +3429,12 @@
 					  u16 *data, bool read, bool page_set)
 {
 	s32 ret_val;
-	u16 reg = BM_PHY_REG_NUM(offset);
-	u16 page = BM_PHY_REG_PAGE(offset);
+	u16 reg, page;
 	u16 phy_reg = 0;
 
 	DEBUGFUNC("e1000_access_phy_wakeup_reg_bm");
+	reg = BM_PHY_REG_NUM(offset);
+	page = BM_PHY_REG_PAGE(offset);
 
 	/* Gig must be disabled for MDIO accesses to Host Wakeup reg page */
 	if ((hw->mac.type == e1000_pchlan) &&
@@ -3465,16 +3492,10 @@
 void e1000_power_up_phy_copper(struct e1000_hw *hw)
 {
 	u16 mii_reg = 0;
-	u16 power_reg = 0;
 
 	/* The PHY will retain its settings across a power down/up cycle */
 	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
 	mii_reg &= ~MII_CR_POWER_DOWN;
-	if (hw->phy.type == e1000_phy_i210) {
-		hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg);
-		power_reg &= ~GS40G_CS_POWER_DOWN;
-		hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
-	}
 	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
 }
 
@@ -3489,17 +3510,10 @@
 void e1000_power_down_phy_copper(struct e1000_hw *hw)
 {
 	u16 mii_reg = 0;
-	u16 power_reg = 0;
 
 	/* The PHY will retain its settings across a power down/up cycle */
 	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
 	mii_reg |= MII_CR_POWER_DOWN;
-	/* i210 Phy requires an additional bit for power up/down */
-	if (hw->phy.type == e1000_phy_i210) {
-		hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg);
-		power_reg |= GS40G_CS_POWER_DOWN;
-		hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
-	}
 	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
 	msec_delay(1);
 }
@@ -3777,8 +3791,8 @@
 	DEBUGFUNC("e1000_access_phy_debug_regs_hv");
 
 	/* This takes care of the difference with desktop vs mobile phy */
-	addr_reg = (hw->phy.type == e1000_phy_82578) ?
-		   I82578_ADDR_REG : I82577_ADDR_REG;
+	addr_reg = ((hw->phy.type == e1000_phy_82578) ?
+		    I82578_ADDR_REG : I82577_ADDR_REG);
 	data_reg = addr_reg + 1;
 
 	/* All operations in this function are phy address 2 */
@@ -3834,8 +3848,8 @@
 	if (ret_val)
 		return ret_val;
 
-	data &= BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
-		BM_CS_STATUS_SPEED_MASK;
+	data &= (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
+		 BM_CS_STATUS_SPEED_MASK);
 
 	if (data != (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
 		     BM_CS_STATUS_SPEED_1000))
@@ -3873,9 +3887,9 @@
 	ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
 
 	if (!ret_val)
-		phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY)
-				      ? e1000_rev_polarity_reversed
-				      : e1000_rev_polarity_normal;
+		phy->cable_polarity = ((data & I82577_PHY_STATUS2_REV_POLARITY)
+				       ? e1000_rev_polarity_reversed
+				       : e1000_rev_polarity_normal);
 
 	return ret_val;
 }
@@ -4010,8 +4024,8 @@
 	if (ret_val)
 		return ret_val;
 
-	length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
-		 I82577_DSTATUS_CABLE_LENGTH_SHIFT;
+	length = ((phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
+		  I82577_DSTATUS_CABLE_LENGTH_SHIFT);
 
 	if (length == E1000_CABLE_LENGTH_UNDEFINED)
 		return -E1000_ERR_PHY;
@@ -4084,3 +4098,157 @@
 	return ret_val;
 }
 
+/**
+ *  e1000_read_phy_reg_mphy - Read mPHY control register
+ *  @hw: pointer to the HW structure
+ *  @address: address to be read
+ *  @data: pointer to the read data
+ *
+ *  Reads the mPHY control register in the PHY at offset and stores the
+ *  information read to data.
+ **/
+s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data)
+{
+	u32 mphy_ctrl = 0;
+	bool locked = FALSE;
+	bool ready;
+
+	DEBUGFUNC("e1000_read_phy_reg_mphy");
+
+	/* Check if mPHY is ready to read/write operations */
+	ready = e1000_is_mphy_ready(hw);
+	if (!ready)
+		return -E1000_ERR_PHY;
+
+	/* Check if mPHY access is disabled and enable it if so */
+	mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
+	if (mphy_ctrl & E1000_MPHY_DIS_ACCESS) {
+		locked = TRUE;
+		ready = e1000_is_mphy_ready(hw);
+		if (!ready)
+			return -E1000_ERR_PHY;
+		mphy_ctrl |= E1000_MPHY_ENA_ACCESS;
+		E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
+	}
+
+	/* Set the address that we want to read */
+	ready = e1000_is_mphy_ready(hw);
+	if (!ready)
+		return -E1000_ERR_PHY;
+
+	/* We mask address, because we want to use only current lane */
+	mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK &
+		~E1000_MPHY_ADDRESS_FNC_OVERRIDE) |
+		(address & E1000_MPHY_ADDRESS_MASK);
+	E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
+
+	/* Read data from the address */
+	ready = e1000_is_mphy_ready(hw);
+	if (!ready)
+		return -E1000_ERR_PHY;
+	*data = E1000_READ_REG(hw, E1000_MPHY_DATA);
+
+	/* Disable access to mPHY if it was originally disabled */
+	if (locked)
+		ready = e1000_is_mphy_ready(hw);
+		if (!ready)
+			return -E1000_ERR_PHY;
+		E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL,
+				E1000_MPHY_DIS_ACCESS);
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_write_phy_reg_mphy - Write mPHY control register
+ *  @hw: pointer to the HW structure
+ *  @address: address to write to
+ *  @data: data to write to register at offset
+ *  @line_override: used when we want to use different line than default one
+ *
+ *  Writes data to mPHY control register.
+ **/
+s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
+			     bool line_override)
+{
+	u32 mphy_ctrl = 0;
+	bool locked = FALSE;
+	bool ready;
+
+	DEBUGFUNC("e1000_write_phy_reg_mphy");
+
+	/* Check if mPHY is ready to read/write operations */
+	ready = e1000_is_mphy_ready(hw);
+	if (!ready)
+		return -E1000_ERR_PHY;
+
+	/* Check if mPHY access is disabled and enable it if so */
+	mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
+	if (mphy_ctrl & E1000_MPHY_DIS_ACCESS) {
+		locked = TRUE;
+		ready = e1000_is_mphy_ready(hw);
+		if (!ready)
+			return -E1000_ERR_PHY;
+		mphy_ctrl |= E1000_MPHY_ENA_ACCESS;
+		E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
+	}
+
+	/* Set the address that we want to read */
+	ready = e1000_is_mphy_ready(hw);
+	if (!ready)
+		return -E1000_ERR_PHY;
+
+	/* We mask address, because we want to use only current lane */
+	if (line_override)
+		mphy_ctrl |= E1000_MPHY_ADDRESS_FNC_OVERRIDE;
+	else
+		mphy_ctrl &= ~E1000_MPHY_ADDRESS_FNC_OVERRIDE;
+	mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK) |
+		(address & E1000_MPHY_ADDRESS_MASK);
+	E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
+
+	/* Read data from the address */
+	ready = e1000_is_mphy_ready(hw);
+	if (!ready)
+		return -E1000_ERR_PHY;
+	E1000_WRITE_REG(hw, E1000_MPHY_DATA, data);
+
+	/* Disable access to mPHY if it was originally disabled */
+	if (locked)
+		ready = e1000_is_mphy_ready(hw);
+		if (!ready)
+			return -E1000_ERR_PHY;
+		E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL,
+				E1000_MPHY_DIS_ACCESS);
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_is_mphy_ready - Check if mPHY control register is not busy
+ *  @hw: pointer to the HW structure
+ *
+ *  Returns mPHY control register status.
+ **/
+bool e1000_is_mphy_ready(struct e1000_hw *hw)
+{
+	u16 retry_count = 0;
+	u32 mphy_ctrl = 0;
+	bool ready = FALSE;
+
+	while (retry_count < 2) {
+		mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
+		if (mphy_ctrl & E1000_MPHY_BUSY) {
+			usec_delay(20);
+			retry_count++;
+			continue;
+		}
+		ready = TRUE;
+		break;
+	}
+
+	if (!ready)
+		DEBUGOUT("ERROR READING mPHY control register, phy is busy.\n");
+
+	return ready;
+}

Modified: trunk/sys/dev/e1000/e1000_phy.h
===================================================================
--- trunk/sys/dev/e1000/e1000_phy.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_phy.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_phy.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_phy.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_PHY_H_
 #define _E1000_PHY_H_
@@ -117,6 +116,10 @@
 s32  e1000_get_cable_length_82577(struct e1000_hw *hw);
 s32  e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
 s32  e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
+s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data);
+s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
+			     bool line_override);
+bool e1000_is_mphy_ready(struct e1000_hw *hw);
 
 #define E1000_MAX_PHY_ADDR		8
 
@@ -141,7 +144,6 @@
 #define GS40G_MAC_LB			0x4140
 #define GS40G_MAC_SPEED_1G		0X0006
 #define GS40G_COPPER_SPEC		0x0010
-#define GS40G_CS_POWER_DOWN		0x0002
 
 /* BM/HV Specific Registers */
 #define BM_PORT_CTRL_PAGE		769
@@ -171,7 +173,7 @@
 #define I82577_ADDR_REG			16
 #define I82577_CFG_REG			22
 #define I82577_CFG_ASSERT_CRS_ON_TX	(1 << 15)
-#define I82577_CFG_ENABLE_DOWNSHIFT	(3 << 10) /* auto downshift 100/10 */
+#define I82577_CFG_ENABLE_DOWNSHIFT	(3 << 10) /* auto downshift */
 #define I82577_CTRL_REG			23
 
 /* 82577 specific PHY registers */
@@ -202,6 +204,12 @@
 #define E1000_82580_PM_D3_LPLU		0x0004 /* For all other states */
 #define E1000_82580_PM_GO_LINKD		0x0020 /* Go Link Disconnect */
 
+#define E1000_MPHY_DIS_ACCESS		0x80000000 /* disable_access bit */
+#define E1000_MPHY_ENA_ACCESS		0x40000000 /* enable_access bit */
+#define E1000_MPHY_BUSY			0x00010000 /* busy bit */
+#define E1000_MPHY_ADDRESS_FNC_OVERRIDE	0x20000000 /* fnc_override bit */
+#define E1000_MPHY_ADDRESS_MASK		0x0000FFFF /* address mask */
+
 /* BM PHY Copper Specific Control 1 */
 #define BM_CS_CTRL1			16
 
@@ -217,6 +225,7 @@
 #define HV_M_STATUS_AUTONEG_COMPLETE	0x1000
 #define HV_M_STATUS_SPEED_MASK		0x0300
 #define HV_M_STATUS_SPEED_1000		0x0200
+#define HV_M_STATUS_SPEED_100		0x0100
 #define HV_M_STATUS_LINK_UP		0x0040
 
 #define IGP01E1000_PHY_PCS_INIT_REG	0x00B4
@@ -248,7 +257,7 @@
 #define IGP02E1000_PHY_AGC_C		0x14B1
 #define IGP02E1000_PHY_AGC_D		0x18B1
 
-#define IGP02E1000_AGC_LENGTH_SHIFT	9   /* Course - 15:13, Fine - 12:9 */
+#define IGP02E1000_AGC_LENGTH_SHIFT	9   /* Course=15:13, Fine=12:9 */
 #define IGP02E1000_AGC_LENGTH_MASK	0x7F
 #define IGP02E1000_AGC_RANGE		15
 
@@ -268,8 +277,8 @@
 #define E1000_KMRNCTRLSTA_HD_CTRL	0x10   /* Kumeran HD Control */
 
 #define IFE_PHY_EXTENDED_STATUS_CONTROL	0x10
-#define IFE_PHY_SPECIAL_CONTROL		0x11 /* 100BaseTx PHY Special Control */
-#define IFE_PHY_SPECIAL_CONTROL_LED	0x1B /* PHY Special and LED Control */
+#define IFE_PHY_SPECIAL_CONTROL		0x11 /* 100BaseTx PHY Special Ctrl */
+#define IFE_PHY_SPECIAL_CONTROL_LED	0x1B /* PHY Special and LED Ctrl */
 #define IFE_PHY_MDIX_CONTROL		0x1C /* MDI/MDI-X Control */
 
 /* IFE PHY Extended Status Control */

Modified: trunk/sys/dev/e1000/e1000_regs.h
===================================================================
--- trunk/sys/dev/e1000/e1000_regs.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_regs.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_regs.h 248292 2013-03-14 22:55:59Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_regs.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_REGS_H_
 #define _E1000_REGS_H_
@@ -51,11 +50,16 @@
 #define E1000_BARCTRL			0x5BBC /* BAR ctrl reg */
 #define E1000_BARCTRL_FLSIZE		0x0700 /* BAR ctrl Flsize */
 #define E1000_BARCTRL_CSRSIZE		0x2000 /* BAR ctrl CSR size */
+#define E1000_MPHY_ADDR_CTRL	0x0024 /* GbE MPHY Address Control */
+#define E1000_MPHY_DATA		0x0E10 /* GBE MPHY Data */
+#define E1000_MPHY_STAT		0x0E0C /* GBE MPHY Statistics */
+#define E1000_PPHY_CTRL		0x5b48 /* PCIe PHY Control */
 #define E1000_I350_BARCTRL		0x5BFC /* BAR ctrl reg */
 #define E1000_I350_DTXMXPKTSZ		0x355C /* Maximum sent packet size reg*/
 #define E1000_SCTL	0x00024  /* SerDes Control - RW */
 #define E1000_FCAL	0x00028  /* Flow Control Address Low - RW */
 #define E1000_FCAH	0x0002C  /* Flow Control Address High -RW */
+#define E1000_FEXT	0x0002C  /* Future Extended - RW */
 #define E1000_FEXTNVM	0x00028  /* Future Extended NVM - RW */
 #define E1000_FEXTNVM3	0x0003C  /* Future Extended NVM 3 - RW */
 #define E1000_FEXTNVM4	0x00024  /* Future Extended NVM 4 - RW */
@@ -95,6 +99,7 @@
 #define E1000_TBT	0x00448  /* Tx Burst Timer - RW */
 #define E1000_AIT	0x00458  /* Adaptive Interframe Spacing Throttle - RW */
 #define E1000_LEDCTL	0x00E00  /* LED Control - RW */
+#define E1000_LEDMUX	0x08130  /* LED MUX Control */
 #define E1000_EXTCNF_CTRL	0x00F00  /* Extended Configuration Control */
 #define E1000_EXTCNF_SIZE	0x00F08  /* Extended Configuration Size */
 #define E1000_PHY_CTRL	0x00F10  /* PHY Control Register in CSR */
@@ -104,6 +109,7 @@
 #define E1000_PBECCSTS	0x0100C  /* Packet Buffer ECC Status - RW */
 #define E1000_EEMNGCTL	0x01010  /* MNG EEprom Control */
 #define E1000_EEARBC	0x01024  /* EEPROM Auto Read Bus Control */
+#define E1000_EEARBC_I210	0x12024 /* EEPROM Auto Read Bus Control */
 #define E1000_FLASHT	0x01028  /* FLASH Timer Register */
 #define E1000_EEWR	0x0102C  /* EEPROM Write Register - RW */
 #define E1000_FLSWCTL	0x01030  /* FLASH control register */
@@ -153,6 +159,8 @@
 #define E1000_PBRWAC	0x024E8 /* Rx packet buffer wrap around counter - RO */
 #define E1000_RDTR	0x02820  /* Rx Delay Timer - RW */
 #define E1000_RADV	0x0282C  /* Rx Interrupt Absolute Delay Timer - RW */
+#define E1000_EMIADD	0x10     /* Extended Memory Indirect Address */
+#define E1000_EMIDATA	0x11     /* Extended Memory Indirect Data */
 #define E1000_SRWR		0x12018  /* Shadow Ram Write Register - RW */
 #define E1000_I210_FLMNGCTL	0x12038
 #define E1000_I210_FLMNGDATA	0x1203C
@@ -209,6 +217,9 @@
 /* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */
 #define E1000_I210_TXPBS_SIZE(_n, _s)	((_s) << (6 * _n))
 
+#define E1000_MMDAC			13 /* MMD Access Control */
+#define E1000_MMDAAD			14 /* MMD Access Address/Data */
+
 /* Convenience macros
  *
  * Note: "_n" is the queue number of the register to be written to.
@@ -485,8 +496,6 @@
 #define E1000_PBACL	0x05B68  /* MSIx PBA Clear - Read/Write 1's to clear */
 #define E1000_FFLT	0x05F00  /* Flexible Filter Length Table - RW Array */
 #define E1000_HOST_IF	0x08800  /* Host Interface */
-#define E1000_FFMT	0x09000  /* Flexible Filter Mask Table - RW Array */
-#define E1000_FFVT	0x09800  /* Flexible Filter Value Table - RW Array */
 #define E1000_HIBBA	0x8F40   /* Host Interface Buffer Base Address */
 /* Flexible Host Filter Table */
 #define E1000_FHFT(_n)	(0x09000 + ((_n) * 0x100))

Modified: trunk/sys/dev/e1000/e1000_vf.c
===================================================================
--- trunk/sys/dev/e1000/e1000_vf.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_vf.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_vf.c 235527 2012-05-16 22:22:52Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_vf.c 269647 2014-08-06 22:15:01Z jfv $*/
 
 
 #include "e1000_api.h"
@@ -50,7 +49,7 @@
 static s32 e1000_init_hw_vf(struct e1000_hw *hw);
 static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
 static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32);
-static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
+static int  e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
 static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
 
 /**
@@ -160,7 +159,7 @@
  *  In addition, the MAC registers to access PHY/NVM don't exist so we don't
  *  even want any SW to attempt to use them.
  **/
-static s32 e1000_acquire_vf(struct e1000_hw *hw)
+static s32 e1000_acquire_vf(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	return -E1000_ERR_PHY;
 }
@@ -173,7 +172,7 @@
  *  In addition, the MAC registers to access PHY/NVM don't exist so we don't
  *  even want any SW to attempt to use them.
  **/
-static void e1000_release_vf(struct e1000_hw *hw)
+static void e1000_release_vf(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	return;
 }
@@ -184,7 +183,7 @@
  *
  *  Virtual functions cannot change link.
  **/
-static s32 e1000_setup_link_vf(struct e1000_hw *hw)
+static s32 e1000_setup_link_vf(struct e1000_hw E1000_UNUSEDARG *hw)
 {
 	DEBUGFUNC("e1000_setup_link_vf");
 
@@ -321,7 +320,8 @@
  *  @addr: pointer to the receive address
  *  @index receive address array register
  **/
-static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index)
+static int e1000_rar_set_vf(struct e1000_hw *hw, u8 *addr,
+			     u32 E1000_UNUSEDARG index)
 {
 	struct e1000_mbx_info *mbx = &hw->mbx;
 	u32 msgbuf[3];
@@ -342,6 +342,8 @@
 	if (!ret_val &&
 	    (msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK)))
 		e1000_read_mac_addr_vf(hw);
+
+	return E1000_SUCCESS;
 }
 
 /**

Modified: trunk/sys/dev/e1000/e1000_vf.h
===================================================================
--- trunk/sys/dev/e1000/e1000_vf.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/e1000_vf.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2010, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/e1000_vf.h 218530 2011-02-11 01:00:26Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/e1000_vf.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _E1000_VF_H_
 #define _E1000_VF_H_
@@ -42,48 +41,50 @@
 
 struct e1000_hw;
 
-#define E1000_DEV_ID_82576_VF                 0x10CA
-#define E1000_DEV_ID_I350_VF                  0x1520
+#define E1000_DEV_ID_82576_VF		0x10CA
+#define E1000_DEV_ID_I350_VF		0x1520
 
-#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */
+#define E1000_VF_INIT_TIMEOUT		200 /* Num of retries to clear RSTI */
 
 /* Additional Descriptor Control definitions */
-#define E1000_TXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Tx Queue */
-#define E1000_RXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Rx Queue */
+#define E1000_TXDCTL_QUEUE_ENABLE	0x02000000 /* Ena specific Tx Queue */
+#define E1000_RXDCTL_QUEUE_ENABLE	0x02000000 /* Ena specific Rx Queue */
 
 /* SRRCTL bit definitions */
-#define E1000_SRRCTL_BSIZEPKT_SHIFT                     10 /* Shift _right_ */
-#define E1000_SRRCTL_BSIZEHDRSIZE_MASK                  0x00000F00
-#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT                 2  /* Shift _left_ */
-#define E1000_SRRCTL_DESCTYPE_LEGACY                    0x00000000
-#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF                0x02000000
-#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT                 0x04000000
-#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS          0x0A000000
-#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION           0x06000000
+#define E1000_SRRCTL(_n)	((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \
+				 (0x0C00C + ((_n) * 0x40)))
+#define E1000_SRRCTL_BSIZEPKT_SHIFT		10 /* Shift _right_ */
+#define E1000_SRRCTL_BSIZEHDRSIZE_MASK		0x00000F00
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT		2  /* Shift _left_ */
+#define E1000_SRRCTL_DESCTYPE_LEGACY		0x00000000
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF	0x02000000
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT		0x04000000
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS	0x0A000000
+#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION	0x06000000
 #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
-#define E1000_SRRCTL_DESCTYPE_MASK                      0x0E000000
-#define E1000_SRRCTL_DROP_EN                            0x80000000
+#define E1000_SRRCTL_DESCTYPE_MASK		0x0E000000
+#define E1000_SRRCTL_DROP_EN			0x80000000
 
-#define E1000_SRRCTL_BSIZEPKT_MASK      0x0000007F
-#define E1000_SRRCTL_BSIZEHDR_MASK      0x00003F00
+#define E1000_SRRCTL_BSIZEPKT_MASK	0x0000007F
+#define E1000_SRRCTL_BSIZEHDR_MASK	0x00003F00
 
 /* Interrupt Defines */
-#define E1000_EICR     0x01580  /* Ext. Interrupt Cause Read - R/clr */
-#define E1000_EITR(_n) (0x01680 + ((_n) << 2))
-#define E1000_EICS     0x01520  /* Ext. Interrupt Cause Set - W0 */
-#define E1000_EIMS     0x01524  /* Ext. Interrupt Mask Set/Read - RW */
-#define E1000_EIMC     0x01528  /* Ext. Interrupt Mask Clear - WO */
-#define E1000_EIAC     0x0152C  /* Ext. Interrupt Auto Clear - RW */
-#define E1000_EIAM     0x01530  /* Ext. Interrupt Ack Auto Clear Mask - RW */
-#define E1000_IVAR0    0x01700  /* Interrupt Vector Allocation (array) - RW */
-#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
-#define E1000_IVAR_VALID        0x80
+#define E1000_EICR		0x01580 /* Ext. Interrupt Cause Read - R/clr */
+#define E1000_EITR(_n)		(0x01680 + ((_n) << 2))
+#define E1000_EICS		0x01520 /* Ext. Intr Cause Set -W0 */
+#define E1000_EIMS		0x01524 /* Ext. Intr Mask Set/Read -RW */
+#define E1000_EIMC		0x01528 /* Ext. Intr Mask Clear -WO */
+#define E1000_EIAC		0x0152C /* Ext. Intr Auto Clear -RW */
+#define E1000_EIAM		0x01530 /* Ext. Intr Ack Auto Clear Mask -RW */
+#define E1000_IVAR0		0x01700 /* Intr Vector Alloc (array) -RW */
+#define E1000_IVAR_MISC		0x01740 /* IVAR for "other" causes -RW */
+#define E1000_IVAR_VALID	0x80
 
 /* Receive Descriptor - Advanced */
 union e1000_adv_rx_desc {
 	struct {
-		u64 pkt_addr;             /* Packet buffer address */
-		u64 hdr_addr;             /* Header buffer address */
+		u64 pkt_addr; /* Packet buffer address */
+		u64 hdr_addr; /* Header buffer address */
 	} read;
 	struct {
 		struct {
@@ -97,23 +98,23 @@
 				} hs_rss;
 			} lo_dword;
 			union {
-				u32 rss;          /* RSS Hash */
+				u32 rss; /* RSS Hash */
 				struct {
-					u16 ip_id;    /* IP id */
-					u16 csum;     /* Packet Checksum */
+					u16 ip_id; /* IP id */
+					u16 csum; /* Packet Checksum */
 				} csum_ip;
 			} hi_dword;
 		} lower;
 		struct {
-			u32 status_error;     /* ext status/error */
-			u16 length;           /* Packet length */
-			u16 vlan;             /* VLAN tag */
+			u32 status_error; /* ext status/error */
+			u16 length; /* Packet length */
+			u16 vlan; /* VLAN tag */
 		} upper;
 	} wb;  /* writeback */
 };
 
-#define E1000_RXDADV_HDRBUFLEN_MASK      0x7FE0
-#define E1000_RXDADV_HDRBUFLEN_SHIFT     5
+#define E1000_RXDADV_HDRBUFLEN_MASK	0x7FE0
+#define E1000_RXDADV_HDRBUFLEN_SHIFT	5
 
 /* Transmit Descriptor - Advanced */
 union e1000_adv_tx_desc {
@@ -130,15 +131,15 @@
 };
 
 /* Adv Transmit Descriptor Config Masks */
-#define E1000_ADVTXD_DTYP_CTXT    0x00200000 /* Advanced Context Descriptor */
-#define E1000_ADVTXD_DTYP_DATA    0x00300000 /* Advanced Data Descriptor */
-#define E1000_ADVTXD_DCMD_EOP     0x01000000 /* End of Packet */
-#define E1000_ADVTXD_DCMD_IFCS    0x02000000 /* Insert FCS (Ethernet CRC) */
-#define E1000_ADVTXD_DCMD_RS      0x08000000 /* Report Status */
-#define E1000_ADVTXD_DCMD_DEXT    0x20000000 /* Descriptor extension (1=Adv) */
-#define E1000_ADVTXD_DCMD_VLE     0x40000000 /* VLAN pkt enable */
-#define E1000_ADVTXD_DCMD_TSE     0x80000000 /* TCP Seg enable */
-#define E1000_ADVTXD_PAYLEN_SHIFT    14 /* Adv desc PAYLEN shift */
+#define E1000_ADVTXD_DTYP_CTXT	0x00200000 /* Advanced Context Descriptor */
+#define E1000_ADVTXD_DTYP_DATA	0x00300000 /* Advanced Data Descriptor */
+#define E1000_ADVTXD_DCMD_EOP	0x01000000 /* End of Packet */
+#define E1000_ADVTXD_DCMD_IFCS	0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_ADVTXD_DCMD_RS	0x08000000 /* Report Status */
+#define E1000_ADVTXD_DCMD_DEXT	0x20000000 /* Descriptor extension (1=Adv) */
+#define E1000_ADVTXD_DCMD_VLE	0x40000000 /* VLAN pkt enable */
+#define E1000_ADVTXD_DCMD_TSE	0x80000000 /* TCP Seg enable */
+#define E1000_ADVTXD_PAYLEN_SHIFT	14 /* Adv desc PAYLEN shift */
 
 /* Context descriptors */
 struct e1000_adv_tx_context_desc {
@@ -148,11 +149,11 @@
 	u32 mss_l4len_idx;
 };
 
-#define E1000_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */
-#define E1000_ADVTXD_TUCMD_IPV4    0x00000400  /* IP Packet Type: 1=IPv4 */
-#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800  /* L4 Packet TYPE of TCP */
-#define E1000_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */
-#define E1000_ADVTXD_MSS_SHIFT      16  /* Adv ctxt MSS shift */
+#define E1000_ADVTXD_MACLEN_SHIFT	9  /* Adv ctxt desc mac len shift */
+#define E1000_ADVTXD_TUCMD_IPV4		0x00000400  /* IP Packet Type: 1=IPv4 */
+#define E1000_ADVTXD_TUCMD_L4T_TCP	0x00000800  /* L4 Packet TYPE of TCP */
+#define E1000_ADVTXD_L4LEN_SHIFT	8  /* Adv ctxt L4LEN shift */
+#define E1000_ADVTXD_MSS_SHIFT		16  /* Adv ctxt MSS shift */
 
 enum e1000_mac_type {
 	e1000_undefined = 0,
@@ -207,7 +208,7 @@
 	s32  (*init_hw)(struct e1000_hw *);
 	s32  (*setup_link)(struct e1000_hw *);
 	void (*write_vfta)(struct e1000_hw *, u32, u32);
-	void (*rar_set)(struct e1000_hw *, u8*, u32);
+	int  (*rar_set)(struct e1000_hw *, u8*, u32);
 	s32  (*read_mac_addr)(struct e1000_hw *);
 };
 

Modified: trunk/sys/dev/e1000/if_em.c
===================================================================
--- trunk/sys/dev/e1000/if_em.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/if_em.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/if_em.c 254573 2013-08-20 17:50:30Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/if_em.c 273912 2014-10-31 18:18:04Z hselasky $*/
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -96,7 +95,7 @@
 /*********************************************************************
  *  Driver version:
  *********************************************************************/
-char em_driver_version[] = "7.3.8";
+char em_driver_version[] = "7.4.2";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -180,6 +179,10 @@
 						PCI_ANY_ID, PCI_ANY_ID, 0},
 	{ 0x8086, E1000_DEV_ID_PCH_LPTLP_I218_V,
 						PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_PCH_I218_LM2,	PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_PCH_I218_V2,	PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_PCH_I218_LM3,	PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_PCH_I218_V3,	PCI_ANY_ID, PCI_ANY_ID, 0},
 	/* required last entry */
 	{ 0, 0, 0, 0, 0}
 };
@@ -698,6 +701,9 @@
 		goto err_late;
 	}
 
+	/* Disable ULP support */
+	e1000_disable_ulp_lpt_lp(hw, TRUE);
+
 	/*
 	**  Do interrupt configuration
 	*/
@@ -1824,7 +1830,6 @@
 	int			nsegs, i, j, first, last = 0;
 	int			error, do_tso, tso_desc = 0, remap = 1;
 
-retry:
 	m_head = *m_headp;
 	txd_upper = txd_lower = txd_used = txd_saved = 0;
 	do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0);
@@ -1950,6 +1955,7 @@
 	tx_buffer_mapped = tx_buffer;
 	map = tx_buffer->map;
 
+retry:
 	error = bus_dmamap_load_mbuf_sg(txr->txtag, map,
 	    *m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
 
@@ -3836,8 +3842,7 @@
 
 	EM_TX_LOCK_ASSERT(txr);
 #ifdef DEV_NETMAP
-	if (netmap_tx_irq(ifp, txr->me |
-	    (NETMAP_LOCKED_ENTER | NETMAP_LOCKED_EXIT)))
+	if (netmap_tx_irq(ifp, txr->me))
 		return;
 #endif /* DEV_NETMAP */
 
@@ -4060,8 +4065,7 @@
 	rxbuf = rxr->rx_buffers;
 	for (int i = 0; i < adapter->num_rx_desc; i++, rxbuf++) {
 		rxbuf = &rxr->rx_buffers[i];
-		error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT,
-		    &rxbuf->map);
+		error = bus_dmamap_create(rxr->rxtag, 0, &rxbuf->map);
 		if (error) {
 			device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
 			    __func__, error);
@@ -4354,7 +4358,7 @@
 		 * preserve the rx buffers passed to userspace.
 		 */
 		if (ifp->if_capenable & IFCAP_NETMAP)
-			rdt -= NA(adapter->ifp)->rx_rings[i].nr_hwavail;
+			rdt -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[i]);
 #endif /* DEV_NETMAP */
 		E1000_WRITE_REG(hw, E1000_RDT(i), rdt);
 	}
@@ -4433,8 +4437,10 @@
 	EM_RX_LOCK(rxr);
 
 #ifdef DEV_NETMAP
-	if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
+	if (netmap_rx_irq(ifp, rxr->me, &processed)) {
+		EM_RX_UNLOCK(rxr);
 		return (FALSE);
+	}
 #endif /* DEV_NETMAP */
 
 	for (i = rxr->next_to_check, processed = 0; count != 0;) {
@@ -4466,6 +4472,7 @@
 			em_rx_discard(rxr, i);
 			goto next_desc;
 		}
+		bus_dmamap_unload(rxr->rxtag, rxr->rx_buffers[i].map);
 
 		/* Assign correct length to the current fragment */
 		mp = rxr->rx_buffers[i].m_head;
@@ -4552,6 +4559,8 @@
 	struct em_buffer	*rbuf;
 
 	rbuf = &rxr->rx_buffers[i];
+	bus_dmamap_unload(rxr->rxtag, rbuf->map);
+
 	/* Free any previous pieces */
 	if (rxr->fmp != NULL) {
 		rxr->fmp->m_flags |= M_PKTHDR;
@@ -5671,7 +5680,7 @@
 	*limit = value;
 	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
-	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
+	    OID_AUTO, name, CTLFLAG_RW, limit, value, description);
 }
 
 

Modified: trunk/sys/dev/e1000/if_em.h
===================================================================
--- trunk/sys/dev/e1000/if_em.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/if_em.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2011, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/if_em.h 250458 2013-05-10 16:16:33Z luigi $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/if_em.h 250458 2013-05-10 16:16:33Z luigi $*/
 
 
 #ifndef _EM_H_DEFINED_

Modified: trunk/sys/dev/e1000/if_igb.c
===================================================================
--- trunk/sys/dev/e1000/if_igb.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/if_igb.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2013, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/if_igb.c 254573 2013-08-20 17:50:30Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/if_igb.c 275836 2014-12-16 19:45:56Z jhb $*/
 
 
 #include "opt_inet.h"
@@ -102,7 +101,7 @@
 /*********************************************************************
  *  Driver version:
  *********************************************************************/
-char igb_driver_version[] = "version - 2.3.10";
+char igb_driver_version[] = "version - 2.4.0";
 
 
 /*********************************************************************
@@ -156,10 +155,19 @@
 	{ 0x8086, E1000_DEV_ID_I210_COPPER_IT,	PCI_ANY_ID, PCI_ANY_ID, 0},
 	{ 0x8086, E1000_DEV_ID_I210_COPPER_OEM1,
 						PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_I210_COPPER_FLASHLESS,
+						PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_I210_SERDES_FLASHLESS,
+						PCI_ANY_ID, PCI_ANY_ID, 0},
 	{ 0x8086, E1000_DEV_ID_I210_FIBER,	PCI_ANY_ID, PCI_ANY_ID, 0},
 	{ 0x8086, E1000_DEV_ID_I210_SERDES,	PCI_ANY_ID, PCI_ANY_ID, 0},
 	{ 0x8086, E1000_DEV_ID_I210_SGMII,	PCI_ANY_ID, PCI_ANY_ID, 0},
 	{ 0x8086, E1000_DEV_ID_I211_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_I354_BACKPLANE_1GBPS,
+						PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_I354_BACKPLANE_2_5GBPS,
+						PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, E1000_DEV_ID_I354_SGMII,	PCI_ANY_ID, PCI_ANY_ID, 0},
 	/* required last entry */
 	{ 0, 0, 0, 0, 0}
 };
@@ -234,9 +242,10 @@
 
 static bool	igb_rxeof(struct igb_queue *, int, int *);
 static void	igb_rx_checksum(u32, struct mbuf *, u32);
-static bool	igb_tx_ctx_setup(struct tx_ring *, struct mbuf *);
-static bool	igb_tso_setup(struct tx_ring *, struct mbuf *, int,
-		    struct ip *, struct tcphdr *);
+static int	igb_tx_ctx_setup(struct tx_ring *,
+		    struct mbuf *, u32 *, u32 *);
+static int	igb_tso_setup(struct tx_ring *,
+		    struct mbuf *, u32 *, u32 *);
 static void	igb_set_promisc(struct adapter *);
 static void	igb_disable_promisc(struct adapter *);
 static void	igb_set_multi(struct adapter *);
@@ -352,7 +361,7 @@
 SYSCTL_INT(_hw_igb, OID_AUTO, max_interrupt_rate, CTLFLAG_RDTUN,
     &igb_max_interrupt_rate, 0, "Maximum interrupts per second");
 
-#if __FreeBSD_version >= 800000
+#ifndef IGB_LEGACY_TX
 /*
 ** Tuneable number of buffers in the buf-ring (drbr_xxx)
 */
@@ -558,7 +567,6 @@
 	 * standard ethernet sized frames.
 	 */
 	adapter->max_frame_size = ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE;
-	adapter->min_frame_size = ETH_ZLEN + ETHERNET_FCS_SIZE;
 
 	/*
 	** Allocate and Setup Queues
@@ -604,8 +612,12 @@
 		    OID_AUTO, "eee_disabled", CTLTYPE_INT|CTLFLAG_RW,
 		    adapter, 0, igb_sysctl_eee, "I",
 		    "Disable Energy Efficient Ethernet");
-		if (adapter->hw.phy.media_type == e1000_media_type_copper)
-			e1000_set_eee_i350(&adapter->hw);
+		if (adapter->hw.phy.media_type == e1000_media_type_copper) {
+			if (adapter->hw.mac.type == e1000_i354)
+				e1000_set_eee_i354(&adapter->hw);
+			else
+				e1000_set_eee_i350(&adapter->hw);
+		}
 	}
 
 	/*
@@ -976,12 +988,12 @@
 	if (err)
 		return (err);
 	if (IGB_TX_TRYLOCK(txr)) {
-		err = igb_mq_start_locked(ifp, txr);
+		igb_mq_start_locked(ifp, txr);
 		IGB_TX_UNLOCK(txr);
 	} else
 		taskqueue_enqueue(que->tq, &txr->txq_task);
 
-	return (err);
+	return (0);
 }
 
 static int
@@ -989,7 +1001,7 @@
 {
 	struct adapter  *adapter = txr->adapter;
         struct mbuf     *next;
-        int             err = 0, enq;
+        int             err = 0, enq = 0;
 
 	IGB_TX_LOCK_ASSERT(txr);
 
@@ -997,7 +1009,6 @@
 	    adapter->link_active == 0)
 		return (ENETDOWN);
 
-	enq = 0;
 
 	/* Process the queue */
 	while ((next = drbr_peek(ifp, txr->br)) != NULL) {
@@ -1225,6 +1236,10 @@
 			ifp->if_capenable ^= IFCAP_TSO4;
 			reinit = 1;
 		}
+		if (mask & IFCAP_TSO6) {
+			ifp->if_capenable ^= IFCAP_TSO6;
+			reinit = 1;
+		}
 		if (mask & IFCAP_VLAN_HWTAGGING) {
 			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
 			reinit = 1;
@@ -1302,7 +1317,7 @@
 #endif
 	}
 
-	if (ifp->if_capenable & IFCAP_TSO4)
+	if (ifp->if_capenable & IFCAP_TSO)
 		ifp->if_hwassist |= CSUM_TSO;
 
 	/* Configure for OS presence */
@@ -1366,8 +1381,12 @@
 	}
 
 	/* Set Energy Efficient Ethernet */
-	if (adapter->hw.phy.media_type == e1000_media_type_copper)
-		e1000_set_eee_i350(&adapter->hw);
+	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
+		if (adapter->hw.mac.type == e1000_i354)
+			e1000_set_eee_i354(&adapter->hw);
+		else
+			e1000_set_eee_i350(&adapter->hw);
+	}
 }
 
 static void
@@ -1735,6 +1754,9 @@
 	case 1000:
 		ifmr->ifm_active |= IFM_1000_T;
 		break;
+	case 2500:
+		ifmr->ifm_active |= IFM_2500_SX;
+		break;
 	}
 
 	if (adapter->link_duplex == FULL_DUPLEX)
@@ -1811,239 +1833,120 @@
 static int
 igb_xmit(struct tx_ring *txr, struct mbuf **m_headp)
 {
-	struct adapter		*adapter = txr->adapter;
-	bus_dma_segment_t	segs[IGB_MAX_SCATTER];
-	bus_dmamap_t		map;
-	struct igb_tx_buffer	*tx_buffer, *tx_buffer_mapped;
-	union e1000_adv_tx_desc	*txd = NULL;
-	struct mbuf		*m_head = *m_headp;
-	struct ether_vlan_header *eh = NULL;
-	struct ip		*ip = NULL;
-	struct tcphdr		*th = NULL;
-	u32			hdrlen, cmd_type_len, olinfo_status = 0;
-	int			ehdrlen, poff;
-	int			nsegs, i, first, last = 0;
-	int			error, do_tso, remap = 1;
+	struct adapter  *adapter = txr->adapter;
+	u32		olinfo_status = 0, cmd_type_len;
+	int             i, j, error, nsegs;
+	int		first;
+	bool		remap = TRUE;
+	struct mbuf	*m_head;
+	bus_dma_segment_t segs[IGB_MAX_SCATTER];
+	bus_dmamap_t	map;
+	struct igb_tx_buf *txbuf;
+	union e1000_adv_tx_desc *txd = NULL;
 
-	/* Set basic descriptor constants */
-	cmd_type_len = E1000_ADVTXD_DTYP_DATA;
-	cmd_type_len |= E1000_ADVTXD_DCMD_IFCS | E1000_ADVTXD_DCMD_DEXT;
+	m_head = *m_headp;
+
+	/* Basic descriptor defines */
+        cmd_type_len = (E1000_ADVTXD_DTYP_DATA |
+	    E1000_ADVTXD_DCMD_IFCS | E1000_ADVTXD_DCMD_DEXT);
+
 	if (m_head->m_flags & M_VLANTAG)
-		cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
+        	cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
 
-retry:
-	m_head = *m_headp;
-	do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0);
-	hdrlen = ehdrlen = poff = 0;
+        /*
+         * Important to capture the first descriptor
+         * used because it will contain the index of
+         * the one we tell the hardware to report back
+         */
+        first = txr->next_avail_desc;
+	txbuf = &txr->tx_buffers[first];
+	map = txbuf->map;
 
 	/*
-	 * Intel recommends entire IP/TCP header length reside in a single
-	 * buffer. If multiple descriptors are used to describe the IP and
-	 * TCP header, each descriptor should describe one or more
-	 * complete headers; descriptors referencing only parts of headers
-	 * are not supported. If all layer headers are not coalesced into
-	 * a single buffer, each buffer should not cross a 4KB boundary,
-	 * or be larger than the maximum read request size.
-	 * Controller also requires modifing IP/TCP header to make TSO work
-	 * so we firstly get a writable mbuf chain then coalesce ethernet/
-	 * IP/TCP header into a single buffer to meet the requirement of
-	 * controller. This also simplifies IP/TCP/UDP checksum offloading
-	 * which also has similiar restrictions.
+	 * Map the packet for DMA.
 	 */
-	if (do_tso || m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) {
-		if (do_tso || (m_head->m_next != NULL && 
-		    m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)) {
-			if (M_WRITABLE(*m_headp) == 0) {
-				m_head = m_dup(*m_headp, M_NOWAIT);
-				m_freem(*m_headp);
-				if (m_head == NULL) {
-					*m_headp = NULL;
-					return (ENOBUFS);
-				}
-				*m_headp = m_head;
-			}
-		}
-		/*
-		 * Assume IPv4, we don't have TSO/checksum offload support
-		 * for IPv6 yet.
-		 */
-		ehdrlen = sizeof(struct ether_header);
-		m_head = m_pullup(m_head, ehdrlen);
-		if (m_head == NULL) {
-			*m_headp = NULL;
-			return (ENOBUFS);
-		}
-		eh = mtod(m_head, struct ether_vlan_header *);
-		if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
-			ehdrlen = sizeof(struct ether_vlan_header);
-			m_head = m_pullup(m_head, ehdrlen);
-			if (m_head == NULL) {
-				*m_headp = NULL;
-				return (ENOBUFS);
-			}
-		}
-		m_head = m_pullup(m_head, ehdrlen + sizeof(struct ip));
-		if (m_head == NULL) {
-			*m_headp = NULL;
-			return (ENOBUFS);
-		}
-		ip = (struct ip *)(mtod(m_head, char *) + ehdrlen);
-		poff = ehdrlen + (ip->ip_hl << 2);
-		if (do_tso) {
-			m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
-			if (m_head == NULL) {
-				*m_headp = NULL;
-				return (ENOBUFS);
-			}
-			/*
-			 * The pseudo TCP checksum does not include TCP payload
-			 * length so driver should recompute the checksum here
-			 * what hardware expect to see. This is adherence of
-			 * Microsoft's Large Send specification.
-			 */
-			th = (struct tcphdr *)(mtod(m_head, char *) + poff);
-			th->th_sum = in_pseudo(ip->ip_src.s_addr,
-			    ip->ip_dst.s_addr, htons(IPPROTO_TCP));
-			/* Keep track of the full header length */
-			hdrlen = poff + (th->th_off << 2);
-		} else if (m_head->m_pkthdr.csum_flags & CSUM_TCP) {
-			m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
-			if (m_head == NULL) {
-				*m_headp = NULL;
-				return (ENOBUFS);
-			}
-			th = (struct tcphdr *)(mtod(m_head, char *) + poff);
-			m_head = m_pullup(m_head, poff + (th->th_off << 2));
-			if (m_head == NULL) {
-				*m_headp = NULL;
-				return (ENOBUFS);
-			}
-			ip = (struct ip *)(mtod(m_head, char *) + ehdrlen);
-			th = (struct tcphdr *)(mtod(m_head, char *) + poff);
-		} else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) {
-			m_head = m_pullup(m_head, poff + sizeof(struct udphdr));
-			if (m_head == NULL) {
-				*m_headp = NULL;
-				return (ENOBUFS);
-			}
-			ip = (struct ip *)(mtod(m_head, char *) + ehdrlen);
-		}
-		*m_headp = m_head;
-	}
-
-	/*
-	 * Map the packet for DMA
-	 *
-	 * Capture the first descriptor index,
-	 * this descriptor will have the index
-	 * of the EOP which is the only one that
-	 * now gets a DONE bit writeback.
-	 */
-	first = txr->next_avail_desc;
-	tx_buffer = &txr->tx_buffers[first];
-	tx_buffer_mapped = tx_buffer;
-	map = tx_buffer->map;
-
+retry:
 	error = bus_dmamap_load_mbuf_sg(txr->txtag, map,
 	    *m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
 
-	/*
-	 * There are two types of errors we can (try) to handle:
-	 * - EFBIG means the mbuf chain was too long and bus_dma ran
-	 *   out of segments.  Defragment the mbuf chain and try again.
-	 * - ENOMEM means bus_dma could not obtain enough bounce buffers
-	 *   at this point in time.  Defer sending and try again later.
-	 * All other errors, in particular EINVAL, are fatal and prevent the
-	 * mbuf chain from ever going through.  Drop it and report error.
-	 */
-	if (error == EFBIG && remap) {
+	if (__predict_false(error)) {
 		struct mbuf *m;
 
-		m = m_defrag(*m_headp, M_NOWAIT);
-		if (m == NULL) {
-			adapter->mbuf_defrag_failed++;
+		switch (error) {
+		case EFBIG:
+			/* Try it again? - one try */
+			if (remap == TRUE) {
+				remap = FALSE;
+				m = m_defrag(*m_headp, M_NOWAIT);
+				if (m == NULL) {
+					adapter->mbuf_defrag_failed++;
+					m_freem(*m_headp);
+					*m_headp = NULL;
+					return (ENOBUFS);
+				}
+				*m_headp = m;
+				goto retry;
+			} else
+				return (error);
+		case ENOMEM:
+			txr->no_tx_dma_setup++;
+			return (error);
+		default:
+			txr->no_tx_dma_setup++;
 			m_freem(*m_headp);
 			*m_headp = NULL;
-			return (ENOBUFS);
+			return (error);
 		}
-		*m_headp = m;
-
-		/* Try it again, but only once */
-		remap = 0;
-		goto retry;
-	} else if (error == ENOMEM) {
-		adapter->no_tx_dma_setup++;
-		return (error);
-	} else if (error != 0) {
-		adapter->no_tx_dma_setup++;
-		m_freem(*m_headp);
-		*m_headp = NULL;
-		return (error);
 	}
 
-	/*
-	** Make sure we don't overrun the ring,
-	** we need nsegs descriptors and one for
-	** the context descriptor used for the
-	** offloads.
-	*/
-        if ((nsegs + 1) > (txr->tx_avail - 2)) {
-                txr->no_desc_avail++;
+	/* Make certain there are enough descriptors */
+	if (nsegs > txr->tx_avail - 2) {
+		txr->no_desc_avail++;
 		bus_dmamap_unload(txr->txtag, map);
 		return (ENOBUFS);
-        }
+	}
 	m_head = *m_headp;
 
-	/* Do hardware assists:
-         * Set up the context descriptor, used
-         * when any hardware offload is done.
-         * This includes CSUM, VLAN, and TSO.
-         * It will use the first descriptor.
-         */
+	/*
+	** Set up the appropriate offload context
+	** this will consume the first descriptor
+	*/
+	error = igb_tx_ctx_setup(txr, m_head, &cmd_type_len, &olinfo_status);
+	if (__predict_false(error)) {
+		m_freem(*m_headp);
+		*m_headp = NULL;
+		return (error);
+	}
 
-	if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
-		if (igb_tso_setup(txr, m_head, ehdrlen, ip, th)) {
-			cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
-			olinfo_status |= E1000_TXD_POPTS_IXSM << 8;
-			olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
-		} else
-			return (ENXIO);
-	} else if (igb_tx_ctx_setup(txr, m_head))
-			olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
-
-	/* Calculate payload length */
-	olinfo_status |= ((m_head->m_pkthdr.len - hdrlen)
-	    << E1000_ADVTXD_PAYLEN_SHIFT);
-
 	/* 82575 needs the queue index added */
 	if (adapter->hw.mac.type == e1000_82575)
 		olinfo_status |= txr->me << 4;
 
-	/* Set up our transmit descriptors */
 	i = txr->next_avail_desc;
-	for (int j = 0; j < nsegs; j++) {
-		bus_size_t seg_len;
-		bus_addr_t seg_addr;
+	for (j = 0; j < nsegs; j++) {
+		bus_size_t seglen;
+		bus_addr_t segaddr;
 
-		tx_buffer = &txr->tx_buffers[i];
-		txd = (union e1000_adv_tx_desc *)&txr->tx_base[i];
-		seg_addr = segs[j].ds_addr;
-		seg_len  = segs[j].ds_len;
+		txbuf = &txr->tx_buffers[i];
+		txd = &txr->tx_base[i];
+		seglen = segs[j].ds_len;
+		segaddr = htole64(segs[j].ds_addr);
 
-		txd->read.buffer_addr = htole64(seg_addr);
-		txd->read.cmd_type_len = htole32(cmd_type_len | seg_len);
+		txd->read.buffer_addr = segaddr;
+		txd->read.cmd_type_len = htole32(E1000_TXD_CMD_IFCS |
+		    cmd_type_len | seglen);
 		txd->read.olinfo_status = htole32(olinfo_status);
-		last = i;
-		if (++i == adapter->num_tx_desc)
+
+		if (++i == txr->num_desc)
 			i = 0;
-		tx_buffer->m_head = NULL;
-		tx_buffer->next_eop = -1;
 	}
 
+	txd->read.cmd_type_len |=
+	    htole32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS);
+	txr->tx_avail -= nsegs;
 	txr->next_avail_desc = i;
-	txr->tx_avail -= nsegs;
-        tx_buffer->m_head = m_head;
 
+	txbuf->m_head = m_head;
 	/*
 	** Here we swap the map so the last descriptor,
 	** which gets the completion interrupt has the
@@ -2050,34 +1953,22 @@
 	** real map, and the first descriptor gets the
 	** unused map from this descriptor.
 	*/
-	tx_buffer_mapped->map = tx_buffer->map;
-	tx_buffer->map = map;
-        bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE);
+	txr->tx_buffers[first].map = txbuf->map;
+	txbuf->map = map;
+	bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE);
 
-        /*
-         * Last Descriptor of Packet
-	 * needs End Of Packet (EOP)
-	 * and Report Status (RS)
-         */
-        txd->read.cmd_type_len |=
-	    htole32(E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS);
-	/*
-	 * Keep track in the first buffer which
-	 * descriptor will be written back
-	 */
-	tx_buffer = &txr->tx_buffers[first];
-	tx_buffer->next_eop = last;
-	/* Update the watchdog time early and often */
-	txr->watchdog_time = ticks;
+        /* Set the EOP descriptor that will be marked done */
+        txbuf = &txr->tx_buffers[first];
+	txbuf->eop = txd;
 
+        bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
+            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	/*
-	 * Advance the Transmit Descriptor Tail (TDT), this tells the E1000
-	 * that this frame is available to transmit.
+	 * Advance the Transmit Descriptor Tail (Tdt), this tells the
+	 * hardware that this frame is available to transmit.
 	 */
-	bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
-	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	++txr->total_packets;
 	E1000_WRITE_REG(&adapter->hw, E1000_TDT(txr->me), i);
-	++txr->tx_packets;
 
 	return (0);
 }
@@ -2346,6 +2237,17 @@
 		if ((ctrl & E1000_CTRL_EXT_LINK_MODE_GMII) &&
 		    (thstat & E1000_THSTAT_LINK_THROTTLE))
 			device_printf(dev, "Link: thermal downshift\n");
+		/* Delay Link Up for Phy update */
+		if (((hw->mac.type == e1000_i210) ||
+		    (hw->mac.type == e1000_i211)) &&
+		    (hw->phy.id == I210_I_PHY_ID))
+			msec_delay(I210_LINK_DELAY);
+		/* Reset if the media type changed. */
+		if (hw->dev_spec._82575.media_changed) {
+			hw->dev_spec._82575.media_changed = false;
+			adapter->flags |= IGB_MEDIA_RESET;
+			igb_reset(adapter);
+		}	
 		/* This can sleep */
 		if_link_state_change(ifp, LINK_STATE_UP);
 	} else if (!link_check && (adapter->link_active == 1)) {
@@ -2478,6 +2380,9 @@
 {
 	device_t		dev = adapter->dev;
 	struct igb_queue	*que = adapter->queues;
+#ifndef IGB_LEGACY_TX
+	struct tx_ring		*txr = adapter->tx_rings;
+#endif
 	int			error, rid = 0;
 
 	/* Turn off all interrupts */
@@ -2497,7 +2402,7 @@
 	}
 
 #ifndef IGB_LEGACY_TX
-	TASK_INIT(&que->txr->txq_task, 0, igb_deferred_mq_start, que->txr);
+	TASK_INIT(&txr->txq_task, 0, igb_deferred_mq_start, txr);
 #endif
 
 	/*
@@ -2634,6 +2539,7 @@
 	switch (adapter->hw.mac.type) {
 	case e1000_82580:
 	case e1000_i350:
+	case e1000_i354:
 	case e1000_i210:
 	case e1000_i211:
 	case e1000_vfadapt:
@@ -2819,7 +2725,7 @@
 
 	if (adapter->msix_mem != NULL)
 		bus_release_resource(dev, SYS_RES_MEMORY,
-		    PCIR_BAR(IGB_MSIX_BAR), adapter->msix_mem);
+		    adapter->memrid, adapter->msix_mem);
 
 	if (adapter->pci_mem != NULL)
 		bus_release_resource(dev, SYS_RES_MEMORY,
@@ -2833,8 +2739,8 @@
 static int
 igb_setup_msix(struct adapter *adapter)
 {
-	device_t dev = adapter->dev;
-	int rid, want, queues, msgs, maxqueues;
+	device_t	dev = adapter->dev;
+	int		bar, want, queues, msgs, maxqueues;
 
 	/* tuneable override */
 	if (igb_enable_msix == 0)
@@ -2844,9 +2750,17 @@
 	msgs = pci_msix_count(dev); 
 	if (msgs == 0)
 		goto msi;
-	rid = PCIR_BAR(IGB_MSIX_BAR);
+	/*
+	** Some new devices, as with ixgbe, now may
+	** use a different BAR, so we need to keep
+	** track of which is used.
+	*/
+	adapter->memrid = PCIR_BAR(IGB_MSIX_BAR);
+	bar = pci_read_config(dev, adapter->memrid, 4);
+	if (bar == 0) /* use next bar */
+		adapter->memrid += 4;
 	adapter->msix_mem = bus_alloc_resource_any(dev,
-	    SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	    SYS_RES_MEMORY, &adapter->memrid, RF_ACTIVE);
        	if (adapter->msix_mem == NULL) {
 		/* May not be enabled */
 		device_printf(adapter->dev,
@@ -2869,6 +2783,7 @@
 		case e1000_82576:
 		case e1000_82580:
 		case e1000_i350:
+		case e1000_i354:
 			maxqueues = 8;
 			break;
 		case e1000_i210:
@@ -2884,6 +2799,10 @@
 	if (queues > maxqueues)
 		queues = maxqueues;
 
+	/* Manual override */
+	if (igb_num_queues != 0)
+		queues = igb_num_queues;
+
 	/*
 	** One vector (RX/TX pair) per queue
 	** plus an additional for Link interrupt
@@ -2927,6 +2846,129 @@
 
 /*********************************************************************
  *
+ *  Initialize the DMA Coalescing feature
+ *
+ **********************************************************************/
+static void
+igb_init_dmac(struct adapter *adapter, u32 pba)
+{
+	device_t	dev = adapter->dev;
+	struct e1000_hw *hw = &adapter->hw;
+	u32 		dmac, reg = ~E1000_DMACR_DMAC_EN;
+	u16		hwm;
+
+	if (hw->mac.type == e1000_i211)
+		return;
+
+	if (hw->mac.type > e1000_82580) {
+
+		if (adapter->dmac == 0) { /* Disabling it */
+			E1000_WRITE_REG(hw, E1000_DMACR, reg);
+			return;
+		} else
+			device_printf(dev, "DMA Coalescing enabled\n");
+
+		/* Set starting threshold */
+		E1000_WRITE_REG(hw, E1000_DMCTXTH, 0);
+
+		hwm = 64 * pba - adapter->max_frame_size / 16;
+		if (hwm < 64 * (pba - 6))
+			hwm = 64 * (pba - 6);
+		reg = E1000_READ_REG(hw, E1000_FCRTC);
+		reg &= ~E1000_FCRTC_RTH_COAL_MASK;
+		reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
+		    & E1000_FCRTC_RTH_COAL_MASK);
+		E1000_WRITE_REG(hw, E1000_FCRTC, reg);
+
+
+		dmac = pba - adapter->max_frame_size / 512;
+		if (dmac < pba - 10)
+			dmac = pba - 10;
+		reg = E1000_READ_REG(hw, E1000_DMACR);
+		reg &= ~E1000_DMACR_DMACTHR_MASK;
+		reg = ((dmac << E1000_DMACR_DMACTHR_SHIFT)
+		    & E1000_DMACR_DMACTHR_MASK);
+
+		/* transition to L0x or L1 if available..*/
+		reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
+
+		/* Check if status is 2.5Gb backplane connection
+		* before configuration of watchdog timer, which is
+		* in msec values in 12.8usec intervals
+		* watchdog timer= msec values in 32usec intervals
+		* for non 2.5Gb connection
+		*/
+		if (hw->mac.type == e1000_i354) {
+			int status = E1000_READ_REG(hw, E1000_STATUS);
+			if ((status & E1000_STATUS_2P5_SKU) &&
+			    (!(status & E1000_STATUS_2P5_SKU_OVER)))
+				reg |= ((adapter->dmac * 5) >> 6);
+			else
+				reg |= (adapter->dmac >> 5);
+		} else {
+			reg |= (adapter->dmac >> 5);
+		}
+
+		E1000_WRITE_REG(hw, E1000_DMACR, reg);
+
+#ifdef I210_OBFF_SUPPORT
+		/*
+		 * Set the OBFF Rx threshold to DMA Coalescing Rx
+		 * threshold - 2KB and enable the feature in the
+		 * hardware for I210.
+		 */
+		if (hw->mac.type == e1000_i210) {
+			int obff = dmac - 2;
+			reg = E1000_READ_REG(hw, E1000_DOBFFCTL);
+			reg &= ~E1000_DOBFFCTL_OBFFTHR_MASK;
+			reg |= (obff & E1000_DOBFFCTL_OBFFTHR_MASK)
+			    | E1000_DOBFFCTL_EXIT_ACT_MASK;
+			E1000_WRITE_REG(hw, E1000_DOBFFCTL, reg);
+		}
+#endif
+		E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
+
+		/* Set the interval before transition */
+		reg = E1000_READ_REG(hw, E1000_DMCTLX);
+		if (hw->mac.type == e1000_i350)
+			reg |= IGB_DMCTLX_DCFLUSH_DIS;
+		/*
+		** in 2.5Gb connection, TTLX unit is 0.4 usec
+		** which is 0x4*2 = 0xA. But delay is still 4 usec
+		*/
+		if (hw->mac.type == e1000_i354) {
+			int status = E1000_READ_REG(hw, E1000_STATUS);
+			if ((status & E1000_STATUS_2P5_SKU) &&
+			    (!(status & E1000_STATUS_2P5_SKU_OVER)))
+				reg |= 0xA;
+			else
+				reg |= 0x4;
+		} else {
+			reg |= 0x4;
+		}
+
+		E1000_WRITE_REG(hw, E1000_DMCTLX, reg);
+
+		/* free space in tx packet buffer to wake from DMA coal */
+		E1000_WRITE_REG(hw, E1000_DMCTXTH, (IGB_TXPBSIZE -
+		    (2 * adapter->max_frame_size)) >> 6);
+
+		/* make low power state decision controlled by DMA coal */
+		reg = E1000_READ_REG(hw, E1000_PCIEMISC);
+		reg &= ~E1000_PCIEMISC_LX_DECISION;
+		E1000_WRITE_REG(hw, E1000_PCIEMISC, reg);
+
+	} else if (hw->mac.type == e1000_82580) {
+		u32 reg = E1000_READ_REG(hw, E1000_PCIEMISC);
+		E1000_WRITE_REG(hw, E1000_PCIEMISC,
+		    reg & ~E1000_PCIEMISC_LX_DECISION);
+		E1000_WRITE_REG(hw, E1000_DMACR, 0);
+	}
+}
+
+
+/*********************************************************************
+ *
  *  Set up an fresh starting state
  *
  **********************************************************************/
@@ -2961,6 +3003,7 @@
 		break;
 	case e1000_82580:
 	case e1000_i350:
+	case e1000_i354:
 	case e1000_vfadapt_i350:
 		pba = E1000_READ_REG(hw, E1000_RXPBS);
 		pba = e1000_rxpbs_adjust_82580(pba);
@@ -3031,70 +3074,19 @@
 	e1000_reset_hw(hw);
 	E1000_WRITE_REG(hw, E1000_WUC, 0);
 
+	/* Reset for AutoMediaDetect */
+	if (adapter->flags & IGB_MEDIA_RESET) {
+		e1000_setup_init_funcs(hw, TRUE);
+		e1000_get_bus_info(hw);
+		adapter->flags &= ~IGB_MEDIA_RESET;
+	}
+
 	if (e1000_init_hw(hw) < 0)
 		device_printf(dev, "Hardware Initialization Failed\n");
 
 	/* Setup DMA Coalescing */
-	if ((hw->mac.type > e1000_82580) &&
-	    (hw->mac.type != e1000_i211)) {
-		u32 dmac;
-		u32 reg = ~E1000_DMACR_DMAC_EN;
+	igb_init_dmac(adapter, pba);
 
-		if (adapter->dmac == 0) { /* Disabling it */
-			E1000_WRITE_REG(hw, E1000_DMACR, reg);
-			goto reset_out;
-		}
-
-		/* Set starting thresholds */
-		E1000_WRITE_REG(hw, E1000_DMCTXTH, 0);
-		E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
-
-		hwm = 64 * pba - adapter->max_frame_size / 16;
-		if (hwm < 64 * (pba - 6))
-			hwm = 64 * (pba - 6);
-		reg = E1000_READ_REG(hw, E1000_FCRTC);
-		reg &= ~E1000_FCRTC_RTH_COAL_MASK;
-		reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
-		    & E1000_FCRTC_RTH_COAL_MASK);
-		E1000_WRITE_REG(hw, E1000_FCRTC, reg);
-
-
-		dmac = pba - adapter->max_frame_size / 512;
-		if (dmac < pba - 10)
-			dmac = pba - 10;
-		reg = E1000_READ_REG(hw, E1000_DMACR);
-		reg &= ~E1000_DMACR_DMACTHR_MASK;
-		reg = ((dmac << E1000_DMACR_DMACTHR_SHIFT)
-		    & E1000_DMACR_DMACTHR_MASK);
-		/* transition to L0x or L1 if available..*/
-		reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
-		/* timer = value in adapter->dmac in 32usec intervals */
-		reg |= (adapter->dmac >> 5);
-		E1000_WRITE_REG(hw, E1000_DMACR, reg);
-
-		/* Set the interval before transition */
-		reg = E1000_READ_REG(hw, E1000_DMCTLX);
-		reg |= 0x80000004;
-		E1000_WRITE_REG(hw, E1000_DMCTLX, reg);
-
-		/* free space in tx packet buffer to wake from DMA coal */
-		E1000_WRITE_REG(hw, E1000_DMCTXTH,
-		    (20480 - (2 * adapter->max_frame_size)) >> 6);
-
-		/* make low power state decision controlled by DMA coal */
-		reg = E1000_READ_REG(hw, E1000_PCIEMISC);
-		reg &= ~E1000_PCIEMISC_LX_DECISION;
-		E1000_WRITE_REG(hw, E1000_PCIEMISC, reg);
-		device_printf(dev, "DMA Coalescing enabled\n");
-
-	} else if (hw->mac.type == e1000_82580) {
-		u32 reg = E1000_READ_REG(hw, E1000_PCIEMISC);
-		E1000_WRITE_REG(hw, E1000_DMACR, 0);
-		E1000_WRITE_REG(hw, E1000_PCIEMISC,
-		    reg & ~E1000_PCIEMISC_LX_DECISION);
-	}
-
-reset_out:
 	E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
 	e1000_get_phy_info(hw);
 	e1000_check_for_link(hw);
@@ -3138,7 +3130,7 @@
 	ifp->if_capabilities = ifp->if_capenable = 0;
 
 	ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
-	ifp->if_capabilities |= IFCAP_TSO4;
+	ifp->if_capabilities |= IFCAP_TSO;
 	ifp->if_capabilities |= IFCAP_JUMBO_MTU;
 	ifp->if_capenable = ifp->if_capabilities;
 
@@ -3344,6 +3336,7 @@
 		txr = &adapter->tx_rings[i];
 		txr->adapter = adapter;
 		txr->me = i;
+		txr->num_desc = adapter->num_tx_desc;
 
 		/* Initialize the TX lock */
 		snprintf(txr->mtx_name, sizeof(txr->mtx_name), "%s:tx(%d)",
@@ -3357,7 +3350,7 @@
 			error = ENOMEM;
 			goto err_tx_desc;
 		}
-		txr->tx_base = (struct e1000_tx_desc *)txr->txdma.dma_vaddr;
+		txr->tx_base = (union e1000_adv_tx_desc *)txr->txdma.dma_vaddr;
 		bzero((void *)txr->tx_base, tsize);
 
         	/* Now allocate transmit buffers for the ring */
@@ -3450,7 +3443,7 @@
 {
 	struct adapter *adapter = txr->adapter;
 	device_t dev = adapter->dev;
-	struct igb_tx_buffer *txbuf;
+	struct igb_tx_buf *txbuf;
 	int error, i;
 
 	/*
@@ -3473,7 +3466,7 @@
 	}
 
 	if (!(txr->tx_buffers =
-	    (struct igb_tx_buffer *) malloc(sizeof(struct igb_tx_buffer) *
+	    (struct igb_tx_buf *) malloc(sizeof(struct igb_tx_buf) *
 	    adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO))) {
 		device_printf(dev, "Unable to allocate tx_buffer memory\n");
 		error = ENOMEM;
@@ -3506,7 +3499,7 @@
 igb_setup_transmit_ring(struct tx_ring *txr)
 {
 	struct adapter *adapter = txr->adapter;
-	struct igb_tx_buffer *txbuf;
+	struct igb_tx_buf *txbuf;
 	int i;
 #ifdef DEV_NETMAP
 	struct netmap_adapter *na = NA(adapter->ifp);
@@ -3542,7 +3535,7 @@
 		}
 #endif /* DEV_NETMAP */
 		/* clear the watch index */
-		txbuf->next_eop = -1;
+		txbuf->eop = NULL;
         }
 
 	/* Set number of descriptors available */
@@ -3656,7 +3649,7 @@
 igb_free_transmit_buffers(struct tx_ring *txr)
 {
 	struct adapter *adapter = txr->adapter;
-	struct igb_tx_buffer *tx_buffer;
+	struct igb_tx_buf *tx_buffer;
 	int             i;
 
 	INIT_DEBUGOUT("free_transmit_ring: begin");
@@ -3703,44 +3696,100 @@
 
 /**********************************************************************
  *
- *  Setup work for hardware segmentation offload (TSO)
+ *  Setup work for hardware segmentation offload (TSO) on
+ *  adapters using advanced tx descriptors
  *
  **********************************************************************/
-static bool
-igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, int ehdrlen,
-	struct ip *ip, struct tcphdr *th)
+static int
+igb_tso_setup(struct tx_ring *txr, struct mbuf *mp,
+    u32 *cmd_type_len, u32 *olinfo_status)
 {
 	struct adapter *adapter = txr->adapter;
 	struct e1000_adv_tx_context_desc *TXD;
-	struct igb_tx_buffer        *tx_buffer;
 	u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
-	u32 mss_l4len_idx = 0;
-	u16 vtag = 0;
-	int ctxd, ip_hlen, tcp_hlen;
+	u32 mss_l4len_idx = 0, paylen;
+	u16 vtag = 0, eh_type;
+	int ctxd, ehdrlen, ip_hlen, tcp_hlen;
+	struct ether_vlan_header *eh;
+#ifdef INET6
+	struct ip6_hdr *ip6;
+#endif
+#ifdef INET
+	struct ip *ip;
+#endif
+	struct tcphdr *th;
 
+
+	/*
+	 * Determine where frame payload starts.
+	 * Jump over vlan headers if already present
+	 */
+	eh = mtod(mp, struct ether_vlan_header *);
+	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+		ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+		eh_type = eh->evl_proto;
+	} else {
+		ehdrlen = ETHER_HDR_LEN;
+		eh_type = eh->evl_encap_proto;
+	}
+
+	switch (ntohs(eh_type)) {
+#ifdef INET6
+	case ETHERTYPE_IPV6:
+		ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+		/* XXX-BZ For now we do not pretend to support ext. hdrs. */
+		if (ip6->ip6_nxt != IPPROTO_TCP)
+			return (ENXIO);
+		ip_hlen = sizeof(struct ip6_hdr);
+		ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+		th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen);
+		th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0);
+		type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6;
+		break;
+#endif
+#ifdef INET
+	case ETHERTYPE_IP:
+		ip = (struct ip *)(mp->m_data + ehdrlen);
+		if (ip->ip_p != IPPROTO_TCP)
+			return (ENXIO);
+		ip->ip_sum = 0;
+		ip_hlen = ip->ip_hl << 2;
+		th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
+		th->th_sum = in_pseudo(ip->ip_src.s_addr,
+		    ip->ip_dst.s_addr, htons(IPPROTO_TCP));
+		type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4;
+		/* Tell transmit desc to also do IPv4 checksum. */
+		*olinfo_status |= E1000_TXD_POPTS_IXSM << 8;
+		break;
+#endif
+	default:
+		panic("%s: CSUM_TSO but no supported IP version (0x%04x)",
+		    __func__, ntohs(eh_type));
+		break;
+	}
+
 	ctxd = txr->next_avail_desc;
-	tx_buffer = &txr->tx_buffers[ctxd];
 	TXD = (struct e1000_adv_tx_context_desc *) &txr->tx_base[ctxd];
 
-	ip->ip_sum = 0;
-	ip_hlen = ip->ip_hl << 2;
 	tcp_hlen = th->th_off << 2;
 
+	/* This is used in the transmit desc in encap */
+	paylen = mp->m_pkthdr.len - ehdrlen - ip_hlen - tcp_hlen;
+
 	/* VLAN MACLEN IPLEN */
 	if (mp->m_flags & M_VLANTAG) {
 		vtag = htole16(mp->m_pkthdr.ether_vtag);
-		vlan_macip_lens |= (vtag << E1000_ADVTXD_VLAN_SHIFT);
+                vlan_macip_lens |= (vtag << E1000_ADVTXD_VLAN_SHIFT);
 	}
 
-	vlan_macip_lens |= (ehdrlen << E1000_ADVTXD_MACLEN_SHIFT);
+	vlan_macip_lens |= ehdrlen << E1000_ADVTXD_MACLEN_SHIFT;
 	vlan_macip_lens |= ip_hlen;
-	TXD->vlan_macip_lens |= htole32(vlan_macip_lens);
+	TXD->vlan_macip_lens = htole32(vlan_macip_lens);
 
 	/* ADV DTYPE TUCMD */
 	type_tucmd_mlhl |= E1000_ADVTXD_DCMD_DEXT | E1000_ADVTXD_DTYP_CTXT;
 	type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_TCP;
-	type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4;
-	TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl);
+	TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl);
 
 	/* MSS L4LEN IDX */
 	mss_l4len_idx |= (mp->m_pkthdr.tso_segsz << E1000_ADVTXD_MSS_SHIFT);
@@ -3751,57 +3800,65 @@
 	TXD->mss_l4len_idx = htole32(mss_l4len_idx);
 
 	TXD->seqnum_seed = htole32(0);
-	tx_buffer->m_head = NULL;
-	tx_buffer->next_eop = -1;
 
-	if (++ctxd == adapter->num_tx_desc)
+	if (++ctxd == txr->num_desc)
 		ctxd = 0;
 
 	txr->tx_avail--;
 	txr->next_avail_desc = ctxd;
-	return TRUE;
+	*cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
+	*olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+	*olinfo_status |= paylen << E1000_ADVTXD_PAYLEN_SHIFT;
+	++txr->tso_tx;
+	return (0);
 }
 
-
 /*********************************************************************
  *
- *  Context Descriptor setup for VLAN or CSUM
+ *  Advanced Context Descriptor setup for VLAN, CSUM or TSO
  *
  **********************************************************************/
 
-static bool
-igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
+static int
+igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp,
+    u32 *cmd_type_len, u32 *olinfo_status)
 {
+	struct e1000_adv_tx_context_desc *TXD;
 	struct adapter *adapter = txr->adapter;
-	struct e1000_adv_tx_context_desc *TXD;
-	struct igb_tx_buffer        *tx_buffer;
-	u32 vlan_macip_lens, type_tucmd_mlhl, mss_l4len_idx;
 	struct ether_vlan_header *eh;
-	struct ip *ip = NULL;
+	struct ip *ip;
 	struct ip6_hdr *ip6;
-	int  ehdrlen, ctxd, ip_hlen = 0;
-	u16	etype, vtag = 0;
+	u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0, mss_l4len_idx = 0;
+	int	ehdrlen, ip_hlen = 0;
+	u16	etype;
 	u8	ipproto = 0;
-	bool	offload = TRUE;
+	int	offload = TRUE;
+	int	ctxd = txr->next_avail_desc;
+	u16	vtag = 0;
 
+	/* First check if TSO is to be used */
+	if (mp->m_pkthdr.csum_flags & CSUM_TSO)
+		return (igb_tso_setup(txr, mp, cmd_type_len, olinfo_status));
+
 	if ((mp->m_pkthdr.csum_flags & CSUM_OFFLOAD) == 0)
 		offload = FALSE;
 
-	vlan_macip_lens = type_tucmd_mlhl = mss_l4len_idx = 0;
-	ctxd = txr->next_avail_desc;
-	tx_buffer = &txr->tx_buffers[ctxd];
+	/* Indicate the whole packet as payload when not doing TSO */
+       	*olinfo_status |= mp->m_pkthdr.len << E1000_ADVTXD_PAYLEN_SHIFT;
+
+	/* Now ready a context descriptor */
 	TXD = (struct e1000_adv_tx_context_desc *) &txr->tx_base[ctxd];
 
 	/*
 	** In advanced descriptors the vlan tag must 
-	** be placed into the context descriptor, thus
-	** we need to be here just for that setup.
+	** be placed into the context descriptor. Hence
+	** we need to make one even if not doing offloads.
 	*/
 	if (mp->m_flags & M_VLANTAG) {
 		vtag = htole16(mp->m_pkthdr.ether_vtag);
 		vlan_macip_lens |= (vtag << E1000_ADVTXD_VLAN_SHIFT);
-	} else if (offload == FALSE)
-		return FALSE;
+	} else if (offload == FALSE) /* ... no offload to do */
+		return (0);
 
 	/*
 	 * Determine where frame payload starts.
@@ -3824,10 +3881,6 @@
 		case ETHERTYPE_IP:
 			ip = (struct ip *)(mp->m_data + ehdrlen);
 			ip_hlen = ip->ip_hl << 2;
-			if (mp->m_len < ehdrlen + ip_hlen) {
-				offload = FALSE;
-				break;
-			}
 			ipproto = ip->ip_p;
 			type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4;
 			break;
@@ -3834,6 +3887,7 @@
 		case ETHERTYPE_IPV6:
 			ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
 			ip_hlen = sizeof(struct ip6_hdr);
+			/* XXX-BZ this will go badly in case of ext hdrs. */
 			ipproto = ip6->ip6_nxt;
 			type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6;
 			break;
@@ -3854,6 +3908,7 @@
 			if (mp->m_pkthdr.csum_flags & CSUM_UDP)
 				type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_UDP;
 			break;
+
 #if __FreeBSD_version >= 800000
 		case IPPROTO_SCTP:
 			if (mp->m_pkthdr.csum_flags & CSUM_SCTP)
@@ -3865,29 +3920,28 @@
 			break;
 	}
 
+	if (offload) /* For the TX descriptor setup */
+		*olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+
 	/* 82575 needs the queue index added */
 	if (adapter->hw.mac.type == e1000_82575)
 		mss_l4len_idx = txr->me << 4;
 
 	/* Now copy bits into descriptor */
-	TXD->vlan_macip_lens |= htole32(vlan_macip_lens);
-	TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl);
+	TXD->vlan_macip_lens = htole32(vlan_macip_lens);
+	TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl);
 	TXD->seqnum_seed = htole32(0);
 	TXD->mss_l4len_idx = htole32(mss_l4len_idx);
 
-	tx_buffer->m_head = NULL;
-	tx_buffer->next_eop = -1;
-
 	/* We've consumed the first desc, adjust counters */
-	if (++ctxd == adapter->num_tx_desc)
+	if (++ctxd == txr->num_desc)
 		ctxd = 0;
 	txr->next_avail_desc = ctxd;
 	--txr->tx_avail;
 
-        return (offload);
+        return (0);
 }
 
-
 /**********************************************************************
  *
  *  Examine each tx_buffer in the used queue. If the hardware is done
@@ -3899,91 +3953,104 @@
 static bool
 igb_txeof(struct tx_ring *txr)
 {
-	struct adapter	*adapter = txr->adapter;
-        int first, last, done, processed;
-        struct igb_tx_buffer *tx_buffer;
-        struct e1000_tx_desc   *tx_desc, *eop_desc;
-	struct ifnet   *ifp = adapter->ifp;
+	struct adapter		*adapter = txr->adapter;
+	struct ifnet		*ifp = adapter->ifp;
+	u32			work, processed = 0;
+	u16			limit = txr->process_limit;
+	struct igb_tx_buf	*buf;
+	union e1000_adv_tx_desc *txd;
 
-	IGB_TX_LOCK_ASSERT(txr);
+	mtx_assert(&txr->tx_mtx, MA_OWNED);
 
 #ifdef DEV_NETMAP
-	if (netmap_tx_irq(ifp, txr->me |
-	    (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
+	if (netmap_tx_irq(ifp, txr->me))
 		return (FALSE);
 #endif /* DEV_NETMAP */
-        if (txr->tx_avail == adapter->num_tx_desc) {
+
+	if (txr->tx_avail == txr->num_desc) {
 		txr->queue_status = IGB_QUEUE_IDLE;
-                return FALSE;
+		return FALSE;
 	}
 
-	processed = 0;
-        first = txr->next_to_clean;
-        tx_desc = &txr->tx_base[first];
-        tx_buffer = &txr->tx_buffers[first];
-	last = tx_buffer->next_eop;
-        eop_desc = &txr->tx_base[last];
-
-	/*
-	 * What this does is get the index of the
-	 * first descriptor AFTER the EOP of the 
-	 * first packet, that way we can do the
-	 * simple comparison on the inner while loop.
-	 */
-	if (++last == adapter->num_tx_desc)
- 		last = 0;
-	done = last;
-
+	/* Get work starting point */
+	work = txr->next_to_clean;
+	buf = &txr->tx_buffers[work];
+	txd = &txr->tx_base[work];
+	work -= txr->num_desc; /* The distance to ring end */
         bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+	do {
+		union e1000_adv_tx_desc *eop = buf->eop;
+		if (eop == NULL) /* No work */
+			break;
 
-        while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) {
-		/* We clean the range of the packet */
-		while (first != done) {
-                	tx_desc->upper.data = 0;
-                	tx_desc->lower.data = 0;
-                	tx_desc->buffer_addr = 0;
-                	++txr->tx_avail;
-			++processed;
+		if ((eop->wb.status & E1000_TXD_STAT_DD) == 0)
+			break;	/* I/O not complete */
 
-			if (tx_buffer->m_head) {
+		if (buf->m_head) {
+			txr->bytes +=
+			    buf->m_head->m_pkthdr.len;
+			bus_dmamap_sync(txr->txtag,
+			    buf->map,
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(txr->txtag,
+			    buf->map);
+			m_freem(buf->m_head);
+			buf->m_head = NULL;
+		}
+		buf->eop = NULL;
+		++txr->tx_avail;
+
+		/* We clean the range if multi segment */
+		while (txd != eop) {
+			++txd;
+			++buf;
+			++work;
+			/* wrap the ring? */
+			if (__predict_false(!work)) {
+				work -= txr->num_desc;
+				buf = txr->tx_buffers;
+				txd = txr->tx_base;
+			}
+			if (buf->m_head) {
 				txr->bytes +=
-				    tx_buffer->m_head->m_pkthdr.len;
+				    buf->m_head->m_pkthdr.len;
 				bus_dmamap_sync(txr->txtag,
-				    tx_buffer->map,
+				    buf->map,
 				    BUS_DMASYNC_POSTWRITE);
 				bus_dmamap_unload(txr->txtag,
-				    tx_buffer->map);
+				    buf->map);
+				m_freem(buf->m_head);
+				buf->m_head = NULL;
+			}
+			++txr->tx_avail;
+			buf->eop = NULL;
 
-                        	m_freem(tx_buffer->m_head);
-                        	tx_buffer->m_head = NULL;
-                	}
-			tx_buffer->next_eop = -1;
-			txr->watchdog_time = ticks;
-
-	                if (++first == adapter->num_tx_desc)
-				first = 0;
-
-	                tx_buffer = &txr->tx_buffers[first];
-			tx_desc = &txr->tx_base[first];
 		}
 		++txr->packets;
+		++processed;
 		++ifp->if_opackets;
-		/* See if we can continue to the next packet */
-		last = tx_buffer->next_eop;
-		if (last != -1) {
-        		eop_desc = &txr->tx_base[last];
-			/* Get new done point */
-			if (++last == adapter->num_tx_desc) last = 0;
-			done = last;
-		} else
-			break;
-        }
-        bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
-            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+		txr->watchdog_time = ticks;
 
-        txr->next_to_clean = first;
+		/* Try the next packet */
+		++txd;
+		++buf;
+		++work;
+		/* reset with a wrap */
+		if (__predict_false(!work)) {
+			work -= txr->num_desc;
+			buf = txr->tx_buffers;
+			txd = txr->tx_base;
+		}
+		prefetch(txd);
+	} while (__predict_true(--limit));
 
+	bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+	work += txr->num_desc;
+	txr->next_to_clean = work;
+
 	/*
 	** Watchdog calculation, we know there's
 	** work outstanding or the first return
@@ -3992,18 +4059,14 @@
 	*/
 	if ((!processed) && ((ticks - txr->watchdog_time) > IGB_WATCHDOG))
 		txr->queue_status |= IGB_QUEUE_HUNG;
-        /*
-         * If we have a minimum free,
-         * clear depleted state bit
-         */
-        if (txr->tx_avail >= IGB_QUEUE_THRESHOLD)          
-                txr->queue_status &= ~IGB_QUEUE_DEPLETED;
 
-	/* All clean, turn off the watchdog */
-	if (txr->tx_avail == adapter->num_tx_desc) {
+	if (txr->tx_avail >= IGB_QUEUE_THRESHOLD)
+		txr->queue_status &= ~IGB_QUEUE_DEPLETED;	
+
+	if (txr->tx_avail == txr->num_desc) {
 		txr->queue_status = IGB_QUEUE_IDLE;
 		return (FALSE);
-        }
+	}
 
 	return (TRUE);
 }
@@ -4166,15 +4229,13 @@
 
 	for (i = 0; i < adapter->num_rx_desc; i++) {
 		rxbuf = &rxr->rx_buffers[i];
-		error = bus_dmamap_create(rxr->htag,
-		    BUS_DMA_NOWAIT, &rxbuf->hmap);
+		error = bus_dmamap_create(rxr->htag, 0, &rxbuf->hmap);
 		if (error) {
 			device_printf(dev,
 			    "Unable to create RX head DMA maps\n");
 			goto fail;
 		}
-		error = bus_dmamap_create(rxr->ptag,
-		    BUS_DMA_NOWAIT, &rxbuf->pmap);
+		error = bus_dmamap_create(rxr->ptag, 0, &rxbuf->pmap);
 		if (error) {
 			device_printf(dev,
 			    "Unable to create RX packet DMA maps\n");
@@ -4570,13 +4631,13 @@
 		 * an init() while a netmap client is active must
 		 * preserve the rx buffers passed to userspace.
 		 * In this driver it means we adjust RDT to
-		 * somthing different from next_to_refresh
+		 * something different from next_to_refresh
 		 * (which is not used in netmap mode).
 		 */
 		if (ifp->if_capenable & IFCAP_NETMAP) {
 			struct netmap_adapter *na = NA(adapter->ifp);
 			struct netmap_kring *kring = &na->rx_rings[i];
-			int t = rxr->next_to_refresh - kring->nr_hwavail;
+			int t = rxr->next_to_refresh - nm_kr_rxspace(kring);
 
 			if (t >= adapter->num_rx_desc)
 				t -= adapter->num_rx_desc;
@@ -4694,11 +4755,13 @@
 	if (rbuf->m_head) {
 		m_free(rbuf->m_head);
 		rbuf->m_head = NULL;
+		bus_dmamap_unload(rxr->htag, rbuf->hmap);
 	}
 
 	if (rbuf->m_pack) {
 		m_free(rbuf->m_pack);
 		rbuf->m_pack = NULL;
+		bus_dmamap_unload(rxr->ptag, rbuf->pmap);
 	}
 
 	return;
@@ -4764,8 +4827,10 @@
 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
 #ifdef DEV_NETMAP
-	if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
+	if (netmap_rx_irq(ifp, rxr->me, &processed)) {
+		IGB_RX_UNLOCK(rxr);
 		return (FALSE);
+	}
 #endif /* DEV_NETMAP */
 
 	/* Main clean loop */
@@ -4787,7 +4852,8 @@
 		rxbuf = &rxr->rx_buffers[i];
 		plen = le16toh(cur->wb.upper.length);
 		ptype = le32toh(cur->wb.lower.lo_dword.data) & IGB_PKTTYPE_MASK;
-		if ((adapter->hw.mac.type == e1000_i350) &&
+		if (((adapter->hw.mac.type == e1000_i350) ||
+		    (adapter->hw.mac.type == e1000_i354)) &&
 		    (staterr & E1000_RXDEXT_STATERR_LB))
 			vtag = be16toh(cur->wb.upper.vlan);
 		else
@@ -4820,6 +4886,7 @@
 		** case only the first header is valid.
 		*/
 		if (rxr->hdr_split && rxr->fmp == NULL) {
+			bus_dmamap_unload(rxr->htag, rxbuf->hmap);
 			hlen = (hdr & E1000_RXDADV_HDRBUFLEN_MASK) >>
 			    E1000_RXDADV_HDRBUFLEN_SHIFT;
 			if (hlen > IGB_HDR_BUF)
@@ -4852,6 +4919,7 @@
 			/* clear buf info for refresh */
 			rxbuf->m_pack = NULL;
 		}
+		bus_dmamap_unload(rxr->ptag, rxbuf->pmap);
 
 		++processed; /* So we know when to refresh */
 
@@ -4982,7 +5050,7 @@
 	}
 
 	if (status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) {
-		u16 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+		u64 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
 #if __FreeBSD_version >= 800000
 		if (sctp) /* reassign */
 			type = CSUM_SCTP_VALID;
@@ -5342,9 +5410,15 @@
 	stats->roc += E1000_READ_REG(hw, E1000_ROC);
 	stats->rjc += E1000_READ_REG(hw, E1000_RJC);
 
-	stats->tor += E1000_READ_REG(hw, E1000_TORH);
-	stats->tot += E1000_READ_REG(hw, E1000_TOTH);
+	stats->mgprc += E1000_READ_REG(hw, E1000_MGTPRC);
+	stats->mgpdc += E1000_READ_REG(hw, E1000_MGTPDC);
+	stats->mgptc += E1000_READ_REG(hw, E1000_MGTPTC);
 
+	stats->tor += E1000_READ_REG(hw, E1000_TORL) +
+	    ((u64)E1000_READ_REG(hw, E1000_TORH) << 32);
+	stats->tot += E1000_READ_REG(hw, E1000_TOTL) +
+	    ((u64)E1000_READ_REG(hw, E1000_TOTH) << 32);
+
 	stats->tpr += E1000_READ_REG(hw, E1000_TPR);
 	stats->tpt += E1000_READ_REG(hw, E1000_TPT);
 	stats->ptc64 += E1000_READ_REG(hw, E1000_PTC64);
@@ -5522,8 +5596,8 @@
 	char namebuf[QUEUE_NAME_LEN];
 
 	/* Driver Statistics */
-	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "link_irq", 
-			CTLFLAG_RD, &adapter->link_irq, 0,
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "link_irq", 
+			CTLFLAG_RD, &adapter->link_irq,
 			"Link MSIX IRQ Handled");
 	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped", 
 			CTLFLAG_RD, &adapter->dropped_pkts,
@@ -5572,32 +5646,32 @@
 		queue_list = SYSCTL_CHILDREN(queue_node);
 
 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "interrupt_rate", 
-				CTLFLAG_RD, &adapter->queues[i],
+				CTLTYPE_UINT | CTLFLAG_RD, &adapter->queues[i],
 				sizeof(&adapter->queues[i]),
 				igb_sysctl_interrupt_rate_handler,
 				"IU", "Interrupt Rate");
 
 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head", 
-				CTLFLAG_RD, adapter, E1000_TDH(txr->me),
+				CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_TDH(txr->me),
 				igb_sysctl_reg_handler, "IU",
  				"Transmit Descriptor Head");
 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_tail", 
-				CTLFLAG_RD, adapter, E1000_TDT(txr->me),
+				CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_TDT(txr->me),
 				igb_sysctl_reg_handler, "IU",
  				"Transmit Descriptor Tail");
 		SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "no_desc_avail", 
 				CTLFLAG_RD, &txr->no_desc_avail,
 				"Queue No Descriptor Available");
-		SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "tx_packets",
-				CTLFLAG_RD, &txr->tx_packets,
+		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets",
+				CTLFLAG_RD, &txr->total_packets,
 				"Queue Packets Transmitted");
 
 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_head", 
-				CTLFLAG_RD, adapter, E1000_RDH(rxr->me),
+				CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RDH(rxr->me),
 				igb_sysctl_reg_handler, "IU",
 				"Receive Descriptor Head");
 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_tail", 
-				CTLFLAG_RD, adapter, E1000_RDT(rxr->me),
+				CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RDT(rxr->me),
 				igb_sysctl_reg_handler, "IU",
 				"Receive Descriptor Tail");
 		SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "rx_packets",
@@ -5670,6 +5744,9 @@
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "missed_packets",
 			CTLFLAG_RD, &stats->mpc,
 			"Missed Packets");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_length_errors",
+			CTLFLAG_RD, &stats->rlec,
+			"Receive Length Errors");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_no_buff",
 			CTLFLAG_RD, &stats->rnbc,
 			"Receive No Buffers");
@@ -5678,7 +5755,7 @@
 			"Receive Undersize");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_fragmented",
 			CTLFLAG_RD, &stats->rfc,
-			"Fragmented Packets Received ");
+			"Fragmented Packets Received");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_oversize",
 			CTLFLAG_RD, &stats->roc,
 			"Oversized Packets Received");
@@ -5694,6 +5771,9 @@
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "alignment_errs",
 			CTLFLAG_RD, &stats->algnerrc,
 			"Alignment Errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_no_crs",
+			CTLFLAG_RD, &stats->tncrs,
+			"Transmit with No CRS");
 	/* On 82575 these are collision counts */
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "coll_ext_errs",
 			CTLFLAG_RD, &stats->cexterr,
@@ -5710,10 +5790,22 @@
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xoff_txd",
 			CTLFLAG_RD, &stats->xofftxc,
 			"XOFF Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "unsupported_fc_recvd",
+			CTLFLAG_RD, &stats->fcruc,
+			"Unsupported Flow Control Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mgmt_pkts_recvd",
+			CTLFLAG_RD, &stats->mgprc,
+			"Management Packets Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mgmt_pkts_drop",
+			CTLFLAG_RD, &stats->mgpdc,
+			"Management Packets Dropped");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mgmt_pkts_txd",
+			CTLFLAG_RD, &stats->mgptc,
+			"Management Packets Transmitted");
 	/* Packet Reception Stats */
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_recvd",
 			CTLFLAG_RD, &stats->tpr,
-			"Total Packets Received ");
+			"Total Packets Received");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
 			CTLFLAG_RD, &stats->gprc,
 			"Good Packets Received");
@@ -5725,7 +5817,7 @@
 			"Multicast Packets Received");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_64",
 			CTLFLAG_RD, &stats->prc64,
-			"64 byte frames received ");
+			"64 byte frames received");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127",
 			CTLFLAG_RD, &stats->prc127,
 			"65-127 byte frames received");
@@ -5743,12 +5835,18 @@
 			"1023-1522 byte frames received");
  	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd", 
  			CTLFLAG_RD, &stats->gorc, 
- 			"Good Octets Received"); 
+ 			"Good Octets Received");
+ 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_octets_recvd", 
+ 			CTLFLAG_RD, &stats->tor, 
+ 			"Total Octets Received");
 
 	/* Packet Transmission Stats */
  	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_txd", 
  			CTLFLAG_RD, &stats->gotc, 
  			"Good Octets Transmitted"); 
+ 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_octets_txd", 
+ 			CTLFLAG_RD, &stats->tot, 
+ 			"Total Octets Transmitted");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd",
 			CTLFLAG_RD, &stats->tpt,
 			"Total Packets Transmitted");
@@ -5763,7 +5861,7 @@
 			"Multicast Packets Transmitted");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_64",
 			CTLFLAG_RD, &stats->ptc64,
-			"64 byte frames transmitted ");
+			"64 byte frames transmitted");
 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127",
 			CTLFLAG_RD, &stats->ptc127,
 			"65-127 byte frames transmitted");
@@ -5947,7 +6045,7 @@
 	*limit = value;
 	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
-	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
+	    OID_AUTO, name, CTLFLAG_RW, limit, value, description);
 }
 
 /*
@@ -6030,7 +6128,7 @@
 		default:
 			/* Do nothing, illegal value */
 			adapter->dmac = 0;
-			return (error);
+			return (EINVAL);
 	}
 	/* Reinit the interface */
 	igb_init(adapter);

Modified: trunk/sys/dev/e1000/if_igb.h
===================================================================
--- trunk/sys/dev/e1000/if_igb.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/if_igb.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,7 +1,6 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/if_igb.h 252899 2013-07-06 22:34:42Z jfv $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/if_igb.h 269647 2014-08-06 22:15:01Z jfv $*/
 
 #ifndef _IGB_H_DEFINED_
 #define _IGB_H_DEFINED_
@@ -163,6 +162,9 @@
 /* PHY master/slave setting */
 #define IGB_MASTER_SLAVE		e1000_ms_hw_default
 
+/* Support AutoMediaDetect for Marvell M88 PHY in i354 */
+#define IGB_MEDIA_RESET			(1 << 0)
+
 /*
  * Micellaneous constants
  */
@@ -174,11 +176,13 @@
 #define IGB_SMARTSPEED_MAX		15
 #define IGB_MAX_LOOP			10
 
-#define IGB_RX_PTHRESH			(hw->mac.type <= e1000_82576 ? 16 : 8)
+#define IGB_RX_PTHRESH			((hw->mac.type == e1000_i354) ? 12 : \
+					  ((hw->mac.type <= e1000_82576) ? 16 : 8))
 #define IGB_RX_HTHRESH			8
-#define IGB_RX_WTHRESH			1
+#define IGB_RX_WTHRESH			((hw->mac.type == e1000_82576 && \
+					  adapter->msix_mem) ? 1 : 4)
 
-#define IGB_TX_PTHRESH			8
+#define IGB_TX_PTHRESH			((hw->mac.type == e1000_i354) ? 20 : 8)
 #define IGB_TX_HTHRESH			1
 #define IGB_TX_WTHRESH			((hw->mac.type != e1000_82575 && \
                                           adapter->msix_mem) ? 1 : 16)
@@ -191,11 +195,6 @@
 #define IGB_EEPROM_APME			0x400;
 /* Queue minimum free for use */
 #define IGB_QUEUE_THRESHOLD		(adapter->num_tx_desc / 8)
-/* Queue bit defines */
-#define IGB_QUEUE_IDLE			1
-#define IGB_QUEUE_WORKING		2
-#define IGB_QUEUE_HUNG			4
-#define IGB_QUEUE_DEPLETED		8
 
 /*
  * TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
@@ -229,8 +228,10 @@
 #define IGB_BR_SIZE		4096	/* ring buf size */
 #define IGB_TSO_SIZE		(65535 + sizeof(struct ether_vlan_header))
 #define IGB_TSO_SEG_SIZE	4096	/* Max dma segment size */
+#define IGB_TXPBSIZE		20408
 #define IGB_HDR_BUF		128
 #define IGB_PKTTYPE_MASK	0x0000FFF0
+#define IGB_DMCTLX_DCFLUSH_DIS	0x80000000  /* Disable DMA Coalesce Flush */
 #define ETH_ZLEN		60
 #define ETH_ADDR_LEN		6
 
@@ -246,6 +247,7 @@
 #define IGB_DEFAULT_ITR         ((1000000/IGB_INTS_PER_SEC) << 2)
 
 #define IGB_LINK_ITR            2000
+#define I210_LINK_DELAY		1000
 
 /* Precision Time Sync (IEEE 1588) defines */
 #define ETHERTYPE_IEEE1588	0x88F7
@@ -285,34 +287,42 @@
 };
 
 /*
- * Transmit ring: one per queue
+ * The transmit ring, one per queue
  */
 struct tx_ring {
-	struct adapter		*adapter;
+        struct adapter		*adapter;
+	struct mtx		tx_mtx;
 	u32			me;
-	struct mtx		tx_mtx;
-	char			mtx_name[16];
+	int			watchdog_time;
+	union e1000_adv_tx_desc	*tx_base;
+	struct igb_tx_buf	*tx_buffers;
 	struct igb_dma_alloc	txdma;
-	struct e1000_tx_desc	*tx_base;
-	u32			next_avail_desc;
-	u32			next_to_clean;
 	volatile u16		tx_avail;
-	struct igb_tx_buffer	*tx_buffers;
+	u16			next_avail_desc;
+	u16			next_to_clean;
+	u16			process_limit;
+	u16			num_desc;
+	enum {
+	    IGB_QUEUE_IDLE = 1,
+	    IGB_QUEUE_WORKING = 2,
+	    IGB_QUEUE_HUNG = 4,
+	    IGB_QUEUE_DEPLETED = 8,
+	}			queue_status;
+	u32			txd_cmd;
+	bus_dma_tag_t		txtag;
+	char			mtx_name[16];
 #ifndef IGB_LEGACY_TX
 	struct buf_ring		*br;
 	struct task		txq_task;
 #endif
-	bus_dma_tag_t		txtag;
-
-	u32			bytes;
+	u32			bytes;  /* used for AIM */
 	u32			packets;
-
-	int			queue_status;
-	int			watchdog_time;
-	int			tdt;
-	int			tdh;
+	/* Soft Stats */
+	unsigned long   	tso_tx;
+	unsigned long   	no_tx_map_avail;
+	unsigned long   	no_tx_dma_setup;
 	u64			no_desc_avail;
-	u64			tx_packets;
+	u64			total_packets;
 };
 
 /*
@@ -354,44 +364,39 @@
 };
 
 struct adapter {
-	struct ifnet	*ifp;
-	struct e1000_hw	hw;
+	struct ifnet		*ifp;
+	struct e1000_hw		hw;
 
-	struct e1000_osdep osdep;
-	struct device	*dev;
-	struct cdev	*led_dev;
+	struct e1000_osdep	osdep;
+	struct device		*dev;
+	struct cdev		*led_dev;
 
-	struct resource *pci_mem;
-	struct resource *msix_mem;
-	struct resource	*res;
-	void		*tag;
-	u32		que_mask;
+	struct resource		*pci_mem;
+	struct resource		*msix_mem;
+	int			memrid;
 
-	int		linkvec;
-	int		link_mask;
-	struct task	link_task;
-	int		link_irq;
+	/*
+	 * Interrupt resources: this set is
+	 * either used for legacy, or for Link
+	 * when doing MSIX
+	 */
+	void			*tag;
+	struct resource 	*res;
 
-	struct ifmedia	media;
-	struct callout	timer;
-	int		msix;	/* total vectors allocated */
-	int		if_flags;
-	int		max_frame_size;
-	int		min_frame_size;
-	int		pause_frames;
-	struct mtx	core_mtx;
-	int		igb_insert_vlan_header;
-        u16		num_queues;
-	u16		vf_ifp;  /* a VF interface */
+	struct ifmedia		media;
+	struct callout		timer;
+	int			msix;
+	int			if_flags;
+	int			pause_frames;
 
-	eventhandler_tag vlan_attach;
-	eventhandler_tag vlan_detach;
-	u32		num_vlans;
+	struct mtx		core_mtx;
 
-	/* Management and WOL features */
-	int		wol;
-	int		has_manage;
+	eventhandler_tag 	vlan_attach;
+	eventhandler_tag 	vlan_detach;
 
+	u16			num_vlans;
+	u16			num_queues;
+
 	/*
 	** Shadow VFTA table, this is needed because
 	** the real vlan filter table gets cleared during
@@ -398,66 +403,86 @@
 	** a soft reset and the driver needs to be able
 	** to repopulate it.
 	*/
-	u32		shadow_vfta[IGB_VFTA_SIZE];
+	u32			shadow_vfta[IGB_VFTA_SIZE];
 
 	/* Info about the interface */
-	u16		link_active;
-	u16		fc;
-	u16		link_speed;
-	u16		link_duplex;
-	u32		smartspeed;
-	u32		dmac;
-	int		enable_aim;
+	u32			optics;
+	u32			fc; /* local flow ctrl setting */
+	int			advertise;  /* link speeds */
+	bool			link_active;
+	u16			max_frame_size;
+	u16			num_segs;
+	u16			link_speed;
+	bool			link_up;
+	u32 			linkvec;
+	u16			link_duplex;
+	u32			dmac;
+	int			link_mask;
 
-	/* Interface queues */
+	/* Flags */
+	u32			flags;
+
+	/* Mbuf cluster size */
+	u32			rx_mbuf_sz;
+
+	/* Support for pluggable optics */
+	bool			sfp_probe;
+	struct task     	link_task;  /* Link tasklet */
+	struct task     	mod_task;   /* SFP tasklet */
+	struct task     	msf_task;   /* Multispeed Fiber */
+	struct taskqueue	*tq;
+
+	/*
+	** Queues: 
+	**   This is the irq holder, it has
+	**   and RX/TX pair or rings associated
+	**   with it.
+	*/
 	struct igb_queue	*queues;
 
 	/*
-	 * Transmit rings
+	 * Transmit rings:
+	 *	Allocated at run time, an array of rings.
 	 */
 	struct tx_ring		*tx_rings;
-        u16			num_tx_desc;
+	u32			num_tx_desc;
 
-	/* Multicast array pointer */
-	u8			*mta;
-
-	/* 
-	 * Receive rings
+	/*
+	 * Receive rings:
+	 *	Allocated at run time, an array of rings.
 	 */
 	struct rx_ring		*rx_rings;
-	bool			rx_hdr_split;
-        u16			num_rx_desc;
-	int			rx_process_limit;
-	u32			rx_mbuf_sz;
-	u32			rx_mask;
+	u64			que_mask;
+	u32			num_rx_desc;
 
+	/* Multicast array memory */
+	u8			*mta;
+
 	/* Misc stats maintained by the driver */
-	unsigned long	dropped_pkts;
-	unsigned long	mbuf_defrag_failed;
-	unsigned long	mbuf_header_failed;
-	unsigned long	mbuf_packet_failed;
-	unsigned long	no_tx_map_avail;
-        unsigned long	no_tx_dma_setup;
-	unsigned long	watchdog_events;
-	unsigned long	rx_overruns;
-	unsigned long	device_control;
-	unsigned long	rx_control;
-	unsigned long	int_mask;
-	unsigned long	eint_mask;
-	unsigned long	packet_buf_alloc_rx;
-	unsigned long	packet_buf_alloc_tx;
+	unsigned long   	dropped_pkts;
+	unsigned long   	mbuf_defrag_failed;
+	unsigned long   	mbuf_header_failed;
+	unsigned long   	mbuf_packet_failed;
+	unsigned long		no_tx_dma_setup;
+	unsigned long   	watchdog_events;
+	unsigned long		link_irq;
+	unsigned long		rx_overruns;
+	unsigned long		device_control;
+	unsigned long		rx_control;
+	unsigned long		int_mask;
+	unsigned long		eint_mask;
+	unsigned long		packet_buf_alloc_rx;
+	unsigned long		packet_buf_alloc_tx;
+	/* Used in pf and vf */
+	void			*stats;
 
-	boolean_t       in_detach;
+	int			enable_aim;
+	int			has_manage;
+	int			wol;
+	int			rx_process_limit;
+	u16			vf_ifp;  /* a VF interface */
+	bool			in_detach; /* Used only in igb_ioctl */
 
-#ifdef IGB_IEEE1588
-	/* IEEE 1588 precision time support */
-	struct cyclecounter     cycles;
-	struct nettimer         clock;
-	struct nettime_compare  compare;
-	struct hwtstamp_ctrl    hwtstamp;
-#endif
-
-	void 			*stats;
 };
 
 /* ******************************************************************************
@@ -475,11 +500,10 @@
 	unsigned int index;
 } igb_vendor_info_t;
 
-
-struct igb_tx_buffer {
-	int		next_eop;  /* Index of the desc to watch */
-        struct mbuf    *m_head;
-        bus_dmamap_t    map;         /* bus_dma map for packet */
+struct igb_tx_buf {
+	union e1000_adv_tx_desc	*eop;
+	struct mbuf	*m_head;
+	bus_dmamap_t	map;
 };
 
 struct igb_rx_buf {

Modified: trunk/sys/dev/e1000/if_lem.c
===================================================================
--- trunk/sys/dev/e1000/if_lem.c	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/if_lem.c	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2012, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/if_lem.c 254364 2013-08-15 12:19:16Z scottl $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/if_lem.c 273912 2014-10-31 18:18:04Z hselasky $*/
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -2679,7 +2678,7 @@
 			void *addr;
 
 			addr = PNMB(slot + si, &paddr);
-			adapter->tx_desc_base[si].buffer_addr = htole64(paddr);
+			adapter->tx_desc_base[i].buffer_addr = htole64(paddr);
 			/* reload the map for netmap mode */
 			netmap_load_map(adapter->txtag, tx_buffer->map, addr);
 		}
@@ -2986,7 +2985,7 @@
 	EM_TX_LOCK_ASSERT(adapter);
 
 #ifdef DEV_NETMAP
-	if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
+	if (netmap_tx_irq(ifp, 0))
 		return;
 #endif /* DEV_NETMAP */
         if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
@@ -3369,7 +3368,7 @@
 #ifdef DEV_NETMAP
 	/* preserve buffers already made available to clients */
 	if (ifp->if_capenable & IFCAP_NETMAP)
-		rctl -= NA(adapter->ifp)->rx_rings[0].nr_hwavail;
+		rctl -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[0]);
 #endif /* DEV_NETMAP */
 	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), rctl);
 
@@ -3455,8 +3454,10 @@
 	    BUS_DMASYNC_POSTREAD);
 
 #ifdef DEV_NETMAP
-	if (netmap_rx_irq(ifp, 0 | NETMAP_LOCKED_ENTER, &rx_sent))
+	if (netmap_rx_irq(ifp, 0, &rx_sent)) {
+		EM_RX_UNLOCK(adapter);
 		return (FALSE);
+	}
 #endif /* DEV_NETMAP */
 
 	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
@@ -4647,7 +4648,7 @@
 	*limit = value;
 	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
-	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
+	    OID_AUTO, name, CTLFLAG_RW, limit, value, description);
 }
 
 static void
@@ -4657,5 +4658,5 @@
 	*limit = value;
 	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
-	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
+	    OID_AUTO, name, CTLFLAG_RW, limit, value, description);
 }

Modified: trunk/sys/dev/e1000/if_lem.h
===================================================================
--- trunk/sys/dev/e1000/if_lem.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/e1000/if_lem.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
 /******************************************************************************
 
   Copyright (c) 2001-2011, Intel Corporation 
@@ -31,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: release/9.2.0/sys/dev/e1000/if_lem.h 250458 2013-05-10 16:16:33Z luigi $*/
+/*$FreeBSD: stable/9/sys/dev/e1000/if_lem.h 250458 2013-05-10 16:16:33Z luigi $*/
 
 
 #ifndef _LEM_H_DEFINED_

Modified: trunk/sys/dev/pci/pcireg.h
===================================================================
--- trunk/sys/dev/pci/pcireg.h	2017-03-26 15:51:30 UTC (rev 9505)
+++ trunk/sys/dev/pci/pcireg.h	2017-08-15 10:40:50 UTC (rev 9506)
@@ -23,8 +23,8 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: release/9.2.0/sys/dev/pci/pcireg.h 250964 2013-05-24 09:30:10Z kib $
- * $MidnightBSD$
+ * $FreeBSD: stable/9/sys/dev/pci/pcireg.h 257497 2013-11-01 07:03:44Z kib $
+ *
  */
 
 /*
@@ -752,8 +752,17 @@
 #define	PCIEM_SLOT_STA_EIS		0x0080
 #define	PCIEM_SLOT_STA_DLLSC		0x0100
 #define	PCIER_ROOT_CTL		0x1c
+#define	PCIEM_ROOT_CTL_SERR_CORR	0x0001
+#define	PCIEM_ROOT_CTL_SERR_NONFATAL	0x0002
+#define	PCIEM_ROOT_CTL_SERR_FATAL	0x0004
+#define	PCIEM_ROOT_CTL_PME		0x0008
+#define	PCIEM_ROOT_CTL_CRS_VIS		0x0010
 #define	PCIER_ROOT_CAP		0x1e
+#define	PCIEM_ROOT_CAP_CRS_VIS		0x0001
 #define	PCIER_ROOT_STA		0x20
+#define	PCIEM_ROOT_STA_PME_REQID_MASK	0x0000ffff
+#define	PCIEM_ROOT_STA_PME_STATUS	0x00010000
+#define	PCIEM_ROOT_STA_PME_PEND		0x00020000
 #define	PCIER_DEVICE_CAP2	0x24
 #define	PCIER_DEVICE_CTL2	0x28
 #define	PCIEM_CTL2_COMP_TIMEOUT_VAL	0x000f



More information about the Midnightbsd-cvs mailing list