changeset 10319:0355b7a83c0d

6870811 igb needs to integrate the latest Intel shared code
author zhefeng xu - Sun Microsystems - Beijing China <Jason.Xu@Sun.COM>
date Sun, 16 Aug 2009 19:52:03 +0800
parents 811db323512d
children 35786983c32a
files usr/src/pkgdefs/SUNWigb/postinstall usr/src/uts/common/io/igb/igb_82575.c usr/src/uts/common/io/igb/igb_82575.h usr/src/uts/common/io/igb/igb_api.c usr/src/uts/common/io/igb/igb_api.h usr/src/uts/common/io/igb/igb_defines.h usr/src/uts/common/io/igb/igb_hw.h usr/src/uts/common/io/igb/igb_mac.c usr/src/uts/common/io/igb/igb_mac.h usr/src/uts/common/io/igb/igb_main.c usr/src/uts/common/io/igb/igb_manage.c usr/src/uts/common/io/igb/igb_manage.h usr/src/uts/common/io/igb/igb_nvm.c usr/src/uts/common/io/igb/igb_nvm.h usr/src/uts/common/io/igb/igb_osdep.c usr/src/uts/common/io/igb/igb_osdep.h usr/src/uts/common/io/igb/igb_phy.c usr/src/uts/common/io/igb/igb_phy.h usr/src/uts/common/io/igb/igb_regs.h usr/src/uts/common/io/igb/igb_sw.h
diffstat 20 files changed, 592 insertions(+), 487 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/pkgdefs/SUNWigb/postinstall	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/pkgdefs/SUNWigb/postinstall	Sun Aug 16 19:52:03 2009 +0800
@@ -133,5 +133,7 @@
 	"pciex8086,10d6"
 	"pciex8086,10e6"
 	"pciex8086,10e7"
-	"pciex8086,10e8"'	\
+	"pciex8086,10e8"
+	"pciex8086,150a"
+	"pciex8086,150d"'	\
 	-b "$BASEDIR" igb
--- a/usr/src/uts/common/io/igb/igb_82575.c	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_82575.c	Sun Aug 16 19:52:03 2009 +0800
@@ -26,13 +26,14 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.94 v2008-10-7 */
+/* IntelVersion: 1.123 v2-9-8_2009-6-12 */
 
 /*
  * 82575EB Gigabit Network Connection
  * 82575EB Gigabit Backplane Connection
  * 82575GB Gigabit Network Connection
  * 82576 Gigabit Network Connection
+ * 82576 Quad Port Gigabit Mezzanine Adapter
  */
 
 #include "igb_api.h"
@@ -71,11 +72,8 @@
 static s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
 static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
 static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
-static void e1000_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count);
-static void e1000_update_mc_addr_list_82575(struct e1000_hw *hw,
-    u8 *mc_addr_list, u32 mc_addr_count,
-    u32 rar_used_count, u32 rar_count);
 void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
+static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
 
 /*
  * e1000_init_phy_params_82575 - Init PHY func ptrs.
@@ -279,13 +277,15 @@
 	/* read mac address */
 	mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
 	/* multicast address update */
-	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_82575;
+	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
 	/* writing VFTA */
 	mac->ops.write_vfta = e1000_write_vfta_generic;
 	/* clearing VFTA */
 	mac->ops.clear_vfta = e1000_clear_vfta_generic;
 	/* setting MTA */
 	mac->ops.mta_set = e1000_mta_set_generic;
+	/* ID LED init */
+	mac->ops.id_led_init = e1000_id_led_init_generic;
 	/* blink LED */
 	mac->ops.blink_led = e1000_blink_led_generic;
 	/* setup LED */
@@ -328,11 +328,12 @@
 static s32
 e1000_acquire_phy_82575(struct e1000_hw *hw)
 {
-	u16 mask;
+	u16 mask = E1000_SWFW_PHY0_SM;
 
 	DEBUGFUNC("e1000_acquire_phy_82575");
 
-	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
+	if (hw->bus.func == E1000_FUNC_1)
+		mask = E1000_SWFW_PHY1_SM;
 
 	return (e1000_acquire_swfw_sync_82575(hw, mask));
 }
@@ -346,11 +347,13 @@
 static void
 e1000_release_phy_82575(struct e1000_hw *hw)
 {
-	u16 mask;
+	u16 mask = E1000_SWFW_PHY0_SM;
 
 	DEBUGFUNC("e1000_release_phy_82575");
 
-	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
+	if (hw->bus.func == E1000_FUNC_1)
+		mask = E1000_SWFW_PHY1_SM;
+
 	e1000_release_swfw_sync_82575(hw, mask);
 }
 
@@ -801,7 +804,7 @@
 
 	DEBUGFUNC("e1000_get_cfg_done_82575");
 
-	if (hw->bus.func == 1)
+	if (hw->bus.func == E1000_FUNC_1)
 		mask = E1000_NVM_CFG_DONE_PORT_1;
 
 	while (timeout) {
@@ -868,11 +871,18 @@
 
 	/* SGMII link check is done through the PCS register. */
 	if ((hw->phy.media_type != e1000_media_type_copper) ||
-	    (e1000_sgmii_active_82575(hw)))
+	    (e1000_sgmii_active_82575(hw))) {
 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed,
 		    &duplex);
-	else
+		/*
+		 * Use this flag to determine if link needs to be checked or
+		 * not.  If we have link clear the flag so that we do not
+		 * continue to check for link.
+		 */
+		hw->mac.get_link_status = !hw->mac.serdes_has_link;
+	} else {
 		ret_val = e1000_check_for_copper_link_generic(hw);
+	}
 
 	return (ret_val);
 }
@@ -936,103 +946,6 @@
 }
 
 /*
- * e1000_init_rx_addrs_82575 - Initialize receive address's
- * @hw: pointer to the HW structure
- * @rar_count: receive address registers
- *
- * Setups the receive address registers by setting the base receive address
- * register to the devices MAC address and clearing all the other receive
- * address registers to 0.
- */
-static void
-e1000_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
-{
-	u32 i;
-	u8 addr[6] = {0, 0, 0, 0, 0, 0};
-	/*
-	 * This function is essentially the same as that of
-	 * e1000_init_rx_addrs_generic. However it also takes care
-	 * of the special case where the register offset of the
-	 * second set of RARs begins elsewhere. This is implicitly taken care by
-	 * function e1000_rar_set_generic.
-	 */
-
-	DEBUGFUNC("e1000_init_rx_addrs_82575");
-
-	/* Setup the receive address */
-	DEBUGOUT("Programming MAC Address into RAR[0]\n");
-	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
-
-	/* Zero out the other (rar_entry_count - 1) receive addresses */
-	DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count - 1);
-	for (i = 1; i < rar_count; i++) {
-		hw->mac.ops.rar_set(hw, addr, i);
-	}
-}
-
-/*
- * e1000_update_mc_addr_list_82575 - Update Multicast addresses
- * @hw: pointer to the HW structure
- * @mc_addr_list: array of multicast addresses to program
- * @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
- *
- * Updates the Receive Address Registers and Multicast Table Array.
- * The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this.
- */
-static void
-e1000_update_mc_addr_list_82575(struct e1000_hw *hw,
-    u8 *mc_addr_list, u32 mc_addr_count,
-    u32 rar_used_count, u32 rar_count)
-{
-	u32 hash_value;
-	u32 i;
-	u8 addr[6] = {0, 0, 0, 0, 0, 0};
-	/*
-	 * This function is essentially the same as that of
-	 * e1000_update_mc_addr_list_generic. However it also takes care
-	 * of the special case where the register offset of the
-	 * second set of RARs begins elsewhere. This is implicitly taken care by
-	 * function e1000_rar_set_generic.
-	 */
-
-	DEBUGFUNC("e1000_update_mc_addr_list_82575");
-
-	/*
-	 * Load the first set of multicast addresses into the exact
-	 * filters (RAR).  If there are not enough to fill the RAR
-	 * array, clear the filters.
-	 */
-	for (i = rar_used_count; i < rar_count; i++) {
-		if (mc_addr_count) {
-			e1000_rar_set_generic(hw, mc_addr_list, i);
-			mc_addr_count--;
-			mc_addr_list += ETH_ADDR_LEN;
-		} else {
-			e1000_rar_set_generic(hw, addr, i);
-		}
-	}
-
-	/* Clear the old settings from the MTA */
-	DEBUGOUT("Clearing MTA\n");
-	for (i = 0; i < hw->mac.mta_reg_count; i++) {
-		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
-		E1000_WRITE_FLUSH(hw);
-	}
-
-	/* Load any remaining multicast addresses into the hash table. */
-	for (; mc_addr_count > 0; mc_addr_count--) {
-		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
-		DEBUGOUT1("Hash value = 0x%03X\n", hash_value);
-		hw->mac.ops.mta_set(hw, hash_value);
-		mc_addr_list += ETH_ADDR_LEN;
-	}
-}
-
-/*
  * e1000_shutdown_fiber_serdes_link_82575 - Remove link during power down
  * @hw: pointer to the HW structure
  *
@@ -1045,13 +958,13 @@
 	u32 reg;
 	u16 eeprom_data = 0;
 
-	if (hw->mac.type != e1000_82576 ||
-	    (hw->phy.media_type != e1000_media_type_fiber &&
-	    hw->phy.media_type != e1000_media_type_internal_serdes))
+	if (hw->phy.media_type != e1000_media_type_internal_serdes)
 		return;
 
-	if (hw->bus.func == 0)
+	if (hw->bus.func == E1000_FUNC_0)
 		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+	else if (hw->bus.func == E1000_FUNC_1)
+		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
 
 	/*
 	 * If APM is not enabled in the EEPROM and management interface is
@@ -1076,6 +989,48 @@
 }
 
 /*
+ * e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
+ * @hw: pointer to the HW structure
+ * @enable: state to enter, either enabled or disabled
+ *
+ * enables/disables L2 switch loopback functionality
+ */
+void
+e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
+{
+	u32 reg;
+
+	reg = E1000_READ_REG(hw, E1000_DTXSWC);
+	if (enable)
+		reg |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+	else
+		reg &= ~(E1000_DTXSWC_VMDQ_LOOPBACK_EN);
+
+	E1000_WRITE_REG(hw, E1000_DTXSWC, reg);
+}
+
+/*
+ * e1000_vmdq_set_replication_pf - enable or disable vmdq replication
+ * @hw: pointer to the HW structure
+ * @enable: state to enter, either enabled or disabled
+ *
+ * enables/disables replication of packets across multiple pools
+ */
+void
+e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
+{
+	u32 reg;
+
+	reg = E1000_READ_REG(hw, E1000_VT_CTL);
+	if (enable)
+		reg |= E1000_VT_CTL_VM_REPL_EN;
+	else
+		reg &= ~(E1000_VT_CTL_VM_REPL_EN);
+
+	E1000_WRITE_REG(hw, E1000_VT_CTL, reg);
+}
+
+/*
  * e1000_reset_hw_82575 - Reset hardware
  * @hw: pointer to the HW structure
  *
@@ -1098,6 +1053,12 @@
 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
 	}
 
+	/* set the completion timeout for interface */
+	ret_val = e1000_set_pcie_completion_timeout(hw);
+	if (ret_val) {
+		DEBUGOUT("PCI-E Set completion timeout has failed.\n");
+	}
+
 	DEBUGOUT("Masking off all interrupts\n");
 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
 
@@ -1130,7 +1091,8 @@
 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
 	(void) E1000_READ_REG(hw, E1000_ICR);
 
-	(void) e1000_check_alt_mac_addr_generic(hw);
+	/* Install any alternate MAC address into RAR0 */
+	ret_val = e1000_check_alt_mac_addr_generic(hw);
 
 	return (ret_val);
 }
@@ -1151,7 +1113,7 @@
 	DEBUGFUNC("e1000_init_hw_82575");
 
 	/* Initialize identification LED */
-	ret_val = e1000_id_led_init_generic(hw);
+	ret_val = mac->ops.id_led_init(hw);
 	if (ret_val) {
 		DEBUGOUT("Error initializing identification LED\n");
 		/* This is not fatal and we should not stop init due to this */
@@ -1162,7 +1124,7 @@
 	mac->ops.clear_vfta(hw);
 
 	/* Setup the receive address */
-	e1000_init_rx_addrs_82575(hw, rar_count);
+	e1000_init_rx_addrs_generic(hw, rar_count);
 	/* Zero out the Multicast HASH table */
 	DEBUGOUT("Zeroing the MTA\n");
 	for (i = 0; i < mac->mta_reg_count; i++)
@@ -1193,7 +1155,7 @@
 static s32
 e1000_setup_copper_link_82575(struct e1000_hw *hw)
 {
-	u32 ctrl, led_ctrl;
+	u32 ctrl;
 	s32 ret_val;
 	bool link;
 
@@ -1210,11 +1172,6 @@
 		break;
 	case e1000_phy_igp_3:
 		ret_val = e1000_copper_link_setup_igp(hw);
-		/* Setup activity LED */
-		led_ctrl = E1000_READ_REG(hw, E1000_LEDCTL);
-		led_ctrl &= IGP_ACTIVITY_LED_MASK;
-		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-		E1000_WRITE_REG(hw, E1000_LEDCTL, led_ctrl);
 		break;
 	default:
 		ret_val = -E1000_ERR_PHY;
@@ -1294,13 +1251,13 @@
 	 */
 	E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
 
-	/* Force link up, set 1gb, set both sw defined pins */
+	/* Force link up, set 1gb */
 	reg = E1000_READ_REG(hw, E1000_CTRL);
-	reg |= E1000_CTRL_SLU |
-	    E1000_CTRL_SPD_1000 |
-	    E1000_CTRL_FRCSPD |
-	    E1000_CTRL_SWDPIN0 |
-	    E1000_CTRL_SWDPIN1;
+	reg |= E1000_CTRL_SLU | E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD;
+	if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) {
+		/* set both sw defined pins */
+		reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
+	}
 	E1000_WRITE_REG(hw, E1000_CTRL, reg);
 
 	/* Power on phy for 82576 fiber adapters */
@@ -1376,7 +1333,6 @@
 
 	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
 		switch (hw->phy.media_type) {
-		case e1000_media_type_fiber:
 		case e1000_media_type_internal_serdes:
 			*data = ID_LED_DEFAULT_82575_SERDES;
 			break;
@@ -1469,12 +1425,6 @@
 e1000_sgmii_active_82575(struct e1000_hw *hw)
 {
 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
-
-	DEBUGFUNC("e1000_sgmii_active_82575");
-
-	if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
-		return (false);
-
 	return (dev_spec->sgmii_active);
 }
 
@@ -1540,9 +1490,19 @@
 	s32 ret_val = E1000_SUCCESS;
 
 	DEBUGFUNC("e1000_read_mac_addr_82575");
-	if (e1000_check_alt_mac_addr_generic(hw))
-		ret_val = e1000_read_mac_addr_generic(hw);
 
+	/*
+	 * 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;
+
+	ret_val = e1000_read_mac_addr_generic(hw);
+
+out:
 	return (ret_val);
 }
 
@@ -1708,3 +1668,55 @@
 	(void) E1000_READ_REG(hw, E1000_RNBC);
 	(void) E1000_READ_REG(hw, E1000_MPC);
 }
+
+/*
+ * e1000_set_pcie_completion_timeout - set pci-e completion timeout
+ * @hw: pointer to the HW structure
+ *
+ * The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
+ * however the hardware default for these parts is 500us to 1ms which is less
+ * than the 10ms recommended by the pci-e spec.  To address this we need to
+ * increase the value to either 10ms to 200ms for capability version 1 config,
+ * or 16ms to 55ms for version 2.
+ */
+static s32
+e1000_set_pcie_completion_timeout(struct e1000_hw *hw)
+{
+	u32 gcr = E1000_READ_REG(hw, E1000_GCR);
+	s32 ret_val = E1000_SUCCESS;
+	u16 pcie_devctl2;
+
+	/* only take action if timeout value is defaulted to 0 */
+	if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
+		goto out;
+
+	/*
+	 * if capababilities version is type 1 we can write the
+	 * timeout of 10ms to 200ms through the GCR register
+	 */
+	if (!(gcr & E1000_GCR_CAP_VER2)) {
+		gcr |= E1000_GCR_CMPL_TMOUT_10ms;
+		goto out;
+	}
+
+	/*
+	 * for version 2 capabilities we need to write the config space
+	 * directly in order to set the completion timeout value for
+	 * 16ms to 55ms
+	 */
+	ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
+	    &pcie_devctl2);
+	if (ret_val)
+		goto out;
+
+	pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
+
+	ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
+	    &pcie_devctl2);
+out:
+	/* disable completion timeout resend */
+	gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
+
+	E1000_WRITE_REG(hw, E1000_GCR, gcr);
+	return (ret_val);
+}
--- a/usr/src/uts/common/io/igb/igb_82575.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_82575.h	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.57 v2008-10-7 */
+/* IntelVersion: 1.77 v2-9-8_2009-6-12 */
 
 #ifndef _IGB_82575_H
 #define	_IGB_82575_H
@@ -129,6 +129,7 @@
 #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_BSIZEPKT_MASK	0x0000007F
 #define	E1000_SRRCTL_BSIZEHDR_MASK	0x00003F00
@@ -138,6 +139,7 @@
 
 #define	E1000_MRQC_ENABLE_RSS_4Q		0x00000002
 #define	E1000_MRQC_ENABLE_VMDQ			0x00000003
+#define	E1000_MRQC_ENABLE_VMDQ_RSS_2Q		0x80000000
 #define	E1000_MRQC_RSS_FIELD_IPV4_UDP		0x00400000
 #define	E1000_MRQC_RSS_FIELD_IPV6_UDP		0x00800000
 #define	E1000_MRQC_RSS_FIELD_IPV6_UDP_EX	0x01000000
@@ -214,7 +216,7 @@
 	} wb;		/* writeback */
 };
 
-#define	E1000_RXDADV_RSSTYPE_MASK	0x0000F000
+#define	E1000_RXDADV_RSSTYPE_MASK	0x0000000F
 #define	E1000_RXDADV_RSSTYPE_SHIFT	12
 #define	E1000_RXDADV_HDRBUFLEN_MASK	0x7FE0
 #define	E1000_RXDADV_HDRBUFLEN_SHIFT	5
@@ -316,6 +318,7 @@
 #define	E1000_ADVTXD_TUCMD_IPV6		0x00000000 /* IP Packet Type: 0=IPv6 */
 #define	E1000_ADVTXD_TUCMD_L4T_UDP	0x00000000 /* L4 Packet TYPE of UDP */
 #define	E1000_ADVTXD_TUCMD_L4T_TCP	0x00000800 /* L4 Packet TYPE of TCP */
+#define	E1000_ADVTXD_TUCMD_L4T_SCTP	0x00001000 /* L4 Packet TYPE of SCTP */
 #define	E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP	0x00002000 /* IPSec Type ESP */
 /* IPSec Encrypt Enable for ESP */
 #define	E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN	0x00004000
@@ -358,11 +361,10 @@
 #define	E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5)	/* DCA Tx Desc enable */
 #define	E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11)	/* Tx Desc writeback RO bit */
 
-/* Additional DCA related definitions, note change in position of CPUID */
 #define	E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
 #define	E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
-#define	E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
-#define	E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
+#define	E1000_DCA_TXCTRL_CPUID_SHIFT_82576 24 /* Tx CPUID */
+#define	E1000_DCA_RXCTRL_CPUID_SHIFT_82576 24 /* Rx CPUID */
 
 /* Additional interrupt register bit definitions */
 #define	E1000_ICR_LSECPNS	0x00000020	/* PN threshold - server */
@@ -387,10 +389,14 @@
 #define	E1000_NVM_APME_82575		0x0400
 #define	MAX_NUM_VFS			8
 
-#define	E1000_DTXSWC_MAC_SPOOF_MASK   0x000000FF /* Per VF MAC spoof control */
-#define	E1000_DTXSWC_VLAN_SPOOF_MASK  0x0000FF00 /* Per VF VLAN spoof control */
+/* Per VF MAC spoof control */
+#define	E1000_DTXSWC_MAC_SPOOF_MASK	0x000000FF
+/* Per VF VLAN spoof control */
+#define	E1000_DTXSWC_VLAN_SPOOF_MASK	0x0000FF00
 #define	E1000_DTXSWC_LLE_MASK		0x00FF0000 /* Per VF Local LB enables */
-#define	E1000_DTXSWC_VMDQ_LOOPBACK_EN	(1 << 31)  /* global VF LB enable */
+#define	E1000_DTXSWC_VLAN_SPOOF_SHIFT	8
+#define	E1000_DTXSWC_LLE_SHIFT		16
+#define	E1000_DTXSWC_VMDQ_LOOPBACK_EN	((u32)1 << 31) /* global VF LB enable */
 
 /* Easy defines for setting default pool, would normally be left a zero */
 #define	E1000_VT_CTL_DEFAULT_POOL_SHIFT	7
@@ -402,84 +408,35 @@
 #define	E1000_VT_CTL_VM_REPL_EN		(1 << 30)
 
 /* Per VM Offload register setup */
+#define	E1000_VMOLR_RLPML_MASK	0x00003FFF /* Long Packet Maximum Length mask */
 #define	E1000_VMOLR_LPE		0x00010000 /* Accept Long packet */
+#define	E1000_VMOLR_RSSE	0x00020000 /* Enable RSS */
 #define	E1000_VMOLR_AUPE	0x01000000 /* Accept untagged packets */
+#define	E1000_VMOLR_ROMPE	0x02000000 /* Accept overflow multicast */
+#define	E1000_VMOLR_ROPE	0x04000000 /* Accept overflow unicast */
 #define	E1000_VMOLR_BAM		0x08000000 /* Accept Broadcast packets */
 #define	E1000_VMOLR_MPME	0x10000000 /* Multicast promiscuous mode */
 #define	E1000_VMOLR_STRVLAN	0x40000000 /* Vlan stripping enable */
-
-#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_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_VFMAILBOX_SIZE	16 /* 16 32 bit words - 64 bytes */
+#define	E1000_VMOLR_STRCRC	0x80000000 /* CRC stripping enable */
 
-/*
- * 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
- */
-/* Messages below or'd with this are the ACK */
-#define	E1000_VT_MSGTYPE_ACK	0xF0000000
-/* Messages below or'd with this are the NACK */
-#define	E1000_VT_MSGTYPE_NACK	0xFF000000
-#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)
-
-#define	E1000_VF_MSGTYPE_REQ_MAC	1 /* VF needs to know its MAC */
-#define	E1000_VF_MSGTYPE_VFLR		2 /* VF notifies VFLR to PF */
-#define	E1000_VF_SET_MULTICAST		3 /* VF requests PF to set MC addr */
-#define	E1000_VF_SET_VLAN		4 /* VF requests PF to set VLAN */
+#define	E1000_VLVF_ARRAY_SIZE		32
+#define	E1000_VLVF_VLANID_MASK		0x00000FFF
+#define	E1000_VLVF_POOLSEL_SHIFT	12
+#define	E1000_VLVF_POOLSEL_MASK		(0xFF << E1000_VLVF_POOLSEL_SHIFT)
+#define	E1000_VLVF_LVLAN		0x00100000
+#define	E1000_VLVF_VLANID_ENABLE	0x80000000
 
-/*
- * Add 100h to all PF msgs, leaves room for up to 255 discrete message types
- * from VF to PF - way more than we'll ever need
- */
-/* PF notifies global reset imminent to VF */
-#define	E1000_PF_MSGTYPE_RESET		(1 + 0x100)
-/* PF notifies VF of LSC... VF will see extra msg info for status */
-#define	E1000_PF_MSGTYPE_LSC		(2 + 0x100)
+#define	E1000_VF_INIT_TIMEOUT	200 /* Number of retries to clear RSTI */
 
-#define	E1000_PF_MSG_LSCDOWN		(1 << E1000_VT_MSGINFO_SHIFT)
-#define	E1000_PF_MSG_LSCUP		(2 << E1000_VT_MSGINFO_SHIFT)
-
-#define	ALL_QUEUES	0xFFFF
+#define	E1000_IOVCTL		0x05BBC
+#define	E1000_IOVCTL_REUSE_VFQ	0x00000001
 
-s32 e1000_send_mail_to_pf_vf(struct e1000_hw *hw, u32 *msg,
-    s16 size);
-s32 e1000_receive_mail_from_pf_vf(struct e1000_hw *hw,
-    u32 *msg, s16 size);
-s32 e1000_send_mail_to_vf(struct e1000_hw *hw, u32 *msg,
-    u32 vf_number, s16 size);
-s32 e1000_receive_mail_from_vf(struct e1000_hw *hw, u32 *msg,
-    u32 vf_number, s16 size);
-void e1000_vmdq_loopback_enable_vf(struct e1000_hw *hw);
-void e1000_vmdq_loopback_disable_vf(struct e1000_hw *hw);
-void e1000_vmdq_replication_enable_vf(struct e1000_hw *hw, u32 enables);
-void e1000_vmdq_replication_disable_vf(struct e1000_hw *hw);
-void e1000_vmdq_enable_replication_mode_vf(struct e1000_hw *hw);
-void e1000_vmdq_broadcast_replication_enable_vf(struct e1000_hw *hw,
-    u32 enables);
-void e1000_vmdq_multicast_replication_enable_vf(struct e1000_hw *hw,
-    u32 enables);
-void e1000_vmdq_broadcast_replication_disable_vf(struct e1000_hw *hw,
-    u32 disables);
-void e1000_vmdq_multicast_replication_disable_vf(struct e1000_hw *hw,
-    u32 disables);
-bool e1000_check_for_pf_ack_vf(struct e1000_hw *hw);
-bool e1000_check_for_pf_mail_vf(struct e1000_hw *hw, u32*);
+#define	E1000_RPLOLR_STRVLAN	0x40000000
 
+#define	ALL_QUEUES		0xFFFF
+
+void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
+void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
 
 #ifdef __cplusplus
 }
--- a/usr/src/uts/common/io/igb/igb_api.c	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_api.c	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.107 v2008-10-7 */
+/* IntelVersion: 1.122 v2-9-8_2009-6-12 */
 
 #include "igb_api.h"
 
@@ -138,6 +138,8 @@
 	case E1000_DEV_ID_82576_FIBER:
 	case E1000_DEV_ID_82576_SERDES:
 	case E1000_DEV_ID_82576_QUAD_COPPER:
+	case E1000_DEV_ID_82576_NS:
+	case E1000_DEV_ID_82576_SERDES_QUAD:
 		mac->type = e1000_82576;
 		break;
 	default:
@@ -278,26 +280,17 @@
  * @hw: pointer to the HW structure
  * @mc_addr_list: array of multicast addresses to program
  * @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
  *
- * Updates the Receive Address Registers and Multicast Table Array.
+ * Updates the Multicast Table Array.
  * The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this.  Currently no func pointer
- * exists and all implementations are handled in the generic version of this
- * function.
  */
 void
 e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
-    u32 mc_addr_count, u32 rar_used_count, u32 rar_count)
+    u32 mc_addr_count)
 {
 	if (hw->mac.ops.update_mc_addr_list)
 		hw->mac.ops.update_mc_addr_list(hw,
-		    mc_addr_list,
-		    mc_addr_count,
-		    rar_used_count,
-		    rar_count);
+		    mc_addr_list, mc_addr_count);
 }
 
 /*
@@ -480,6 +473,22 @@
 }
 
 /*
+ * e1000_id_led_init - store LED configurations in SW
+ * @hw: pointer to the HW structure
+ *
+ * Initializes the LED config in SW. This is a function pointer entry point
+ * called by drivers.
+ */
+s32
+e1000_id_led_init(struct e1000_hw *hw)
+{
+	if (hw->mac.ops.id_led_init)
+		return (hw->mac.ops.id_led_init(hw));
+
+	return (E1000_SUCCESS);
+}
+
+/*
  * e1000_led_on - Turn on SW controllable LED
  * @hw: pointer to the HW structure
  *
--- a/usr/src/uts/common/io/igb/igb_api.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_api.h	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.50 v2008-10-7 */
+/* IntelVersion: 1.52 v2-9-8_2009-6-12 */
 
 #ifndef _IGB_API_H
 #define	_IGB_API_H
@@ -62,14 +62,14 @@
 void e1000_mta_set(struct e1000_hw *hw, u32 hash_value);
 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,
-    u32 rar_used_count, u32 rar_count);
+    u8 *mc_addr_list, u32 mc_addr_count);
 s32 e1000_setup_led(struct e1000_hw *hw);
 s32 e1000_cleanup_led(struct e1000_hw *hw);
 s32 e1000_check_reset_block(struct e1000_hw *hw);
 s32 e1000_blink_led(struct e1000_hw *hw);
 s32 e1000_led_on(struct e1000_hw *hw);
 s32 e1000_led_off(struct e1000_hw *hw);
+s32 e1000_id_led_init(struct e1000_hw *hw);
 void e1000_reset_adaptive(struct e1000_hw *hw);
 void e1000_update_adaptive(struct e1000_hw *hw);
 s32 e1000_get_cable_length(struct e1000_hw *hw);
--- a/usr/src/uts/common/io/igb/igb_defines.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_defines.h	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.79 v2008-10-7 */
+/* IntelVersion: 1.111 v2-9-8_2009-6-12 */
 
 #ifndef _IGB_DEFINES_H
 #define	_IGB_DEFINES_H
@@ -131,6 +131,8 @@
 #define	E1000_CTRL_EXT_PFRSTD	0x00004000
 #define	E1000_CTRL_EXT_SPD_BYPS	0x00008000 /* Speed Select Bypass */
 #define	E1000_CTRL_EXT_RO_DIS	0x00020000 /* Relaxed Ordering disable */
+/* DMA Dynamic Clock Gating */
+#define	E1000_CTRL_EXT_DMA_DYN_CLK_EN	0x00080000
 #define	E1000_CTRL_EXT_LINK_MODE_MASK	0x00C00000
 #define	E1000_CTRL_EXT_LINK_MODE_GMII	0x00000000
 #define	E1000_CTRL_EXT_LINK_MODE_TBI	0x00C00000
@@ -382,6 +384,7 @@
 #define	E1000_CTRL_SWDPIN0	0x00040000  /* SWDPIN 0 value */
 #define	E1000_CTRL_SWDPIN1	0x00080000  /* SWDPIN 1 value */
 #define	E1000_CTRL_SWDPIN2	0x00100000  /* SWDPIN 2 value */
+#define	E1000_CTRL_ADVD3WUC	0x00100000  /* D3 WUC */
 #define	E1000_CTRL_SWDPIN3	0x00200000  /* SWDPIN 3 value */
 #define	E1000_CTRL_SWDPIO0	0x00400000  /* SWDPIN 0 Input or output */
 #define	E1000_CTRL_SWDPIO1	0x00800000  /* SWDPIN 1 input or output */
@@ -458,6 +461,7 @@
 #define	E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
 #define	E1000_STATUS_ASDV	0x00000300 /* Auto speed detect value */
 /* Change in Dock/Undock state. Clear on write '0'. */
+#define	E1000_STATUS_PHYRA	0x00000400 /* PHY Reset Asserted */
 #define	E1000_STATUS_DOCK_CI	0x00000800
 #define	E1000_STATUS_GIO_MASTER_ENABLE	0x00080000 /* Master request status */
 #define	E1000_STATUS_MTXCKOK	0x00000400 /* MTX clock running OK */
@@ -667,14 +671,19 @@
 /* PBA constants */
 #define	E1000_PBA_6K	0x0006	/* 6KB */
 #define	E1000_PBA_8K	0x0008	/* 8KB */
+#define	E1000_PBA_10K	0x000A	/* 10KB */
 #define	E1000_PBA_12K	0x000C	/* 12KB */
+#define	E1000_PBA_14K	0x000E	/* 14KB */
 #define	E1000_PBA_16K	0x0010	/* 16KB */
+#define	E1000_PBA_18K	0x0012
 #define	E1000_PBA_20K	0x0014
 #define	E1000_PBA_22K	0x0016
 #define	E1000_PBA_24K	0x0018
+#define	E1000_PBA_26K	0x001A
 #define	E1000_PBA_30K	0x001E
 #define	E1000_PBA_32K	0x0020
 #define	E1000_PBA_34K	0x0022
+#define	E1000_PBA_35K	0x0023
 #define	E1000_PBA_38K	0x0026
 #define	E1000_PBA_40K	0x0028
 #define	E1000_PBA_48K	0x0030    /* 48KB */
@@ -695,6 +704,9 @@
 #define	E1000_SWSM_WMNG		0x00000004 /* Wake MNG Clock */
 #define	E1000_SWSM_DRV_LOAD	0x00000008 /* Driver Loaded Bit */
 
+/* Secondary driver semaphore bit */
+#define	E1000_SWSM2_LOCK	0x00000002
+
 /* Interrupt Cause Read */
 #define	E1000_ICR_TXDW		0x00000001 /* Transmit desc written back */
 #define	E1000_ICR_TXQE		0x00000002 /* Transmit Queue empty */
@@ -871,6 +883,8 @@
 #define	E1000_EICS_TCP_TIMER	E1000_EICR_TCP_TIMER /* TCP Timer */
 #define	E1000_EICS_OTHER	E1000_EICR_OTHER   /* Interrupt Cause Active */
 
+#define	E1000_EITR_ITR_INT_MASK	0x0000FFFF
+
 /* Transmit Descriptor Control */
 #define	E1000_TXDCTL_PTHRESH	0x0000003F /* TXDCTL Prefetch Threshold */
 #define	E1000_TXDCTL_HTHRESH	0x00003F00 /* TXDCTL Host Threshold */
@@ -901,6 +915,10 @@
  */
 #define	E1000_RAR_ENTRIES	15
 #define	E1000_RAH_AV		0x80000000	/* Receive descriptor valid */
+#define	E1000_RAL_MAC_ADDR_LEN	4
+#define	E1000_RAH_MAC_ADDR_LEN	2
+#define	E1000_RAH_POOL_MASK	0x03FC0000
+#define	E1000_RAH_POOL_1	0x00040000
 
 /* Error Codes */
 #define	E1000_SUCCESS		0
@@ -916,6 +934,7 @@
 #define	E1000_BLK_PHY_RESET	12
 #define	E1000_ERR_SWFW_SYNC	13
 #define	E1000_NOT_IMPLEMENTED	14
+#define	E1000_ERR_MBX		15
 
 /* Loop limit on how long we wait for auto-negotiation to complete */
 #define	FIBER_LINK_UP_LIMIT	50
@@ -965,6 +984,10 @@
 #define	E1000_GCR_TXD_NO_SNOOP		0x00000008
 #define	E1000_GCR_TXDSCW_NO_SNOOP	0x00000010
 #define	E1000_GCR_TXDSCR_NO_SNOOP	0x00000020
+#define	E1000_GCR_CMPL_TMOUT_MASK	0x0000F000
+#define	E1000_GCR_CMPL_TMOUT_10ms	0x00001000
+#define	E1000_GCR_CMPL_TMOUT_RESEND	0x00010000
+#define	E1000_GCR_CAP_VER2		0x00040000
 
 #define	PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP	| \
 			E1000_GCR_RXDSCW_NO_SNOOP	| \
@@ -1080,6 +1103,8 @@
 #define	PHY_1000T_STATUS	0x0A /* 1000Base-T Status Reg */
 #define	PHY_EXT_STATUS		0x0F /* Extended Status Reg */
 
+#define	PHY_CONTROL_LB		0x4000 /* PHY Loopback bit */
+
 /* NVM Control */
 #define	E1000_EECD_SK		0x00000001 /* NVM Clock */
 #define	E1000_EECD_CS		0x00000002 /* NVM Chip Select */
@@ -1110,6 +1135,7 @@
 #define	E1000_EECD_SHADV	0x00200000 /* Shadow RAM Data Valid */
 #define	E1000_EECD_SEC1VAL	0x00400000 /* Sector One Valid */
 #define	E1000_EECD_SECVAL_SHIFT		22
+#define	E1000_EECD_SEC1VAL_VALID_MASK	(E1000_EECD_AUTO_RD | E1000_EECD_PRES)
 
 #define	E1000_NVM_SWDPIN0	0x0001	/* SWDPIN 0 NVM Value */
 #define	E1000_NVM_LED_LOGIC	0x0020	/* Led Logic Word */
@@ -1213,22 +1239,14 @@
 #define	IGP_LED3_MODE		0x07000000
 
 /* PCI/PCI-X/PCI-EX Config space */
-#define	PCIX_COMMAND_REGISTER		0xE6
-#define	PCIX_STATUS_REGISTER_LO		0xE8
-#define	PCIX_STATUS_REGISTER_HI		0xEA
 #define	PCI_HEADER_TYPE_REGISTER	0x0E
 #define	PCIE_LINK_STATUS		0x12
+#define	PCIE_DEVICE_CONTROL2		0x28
 
-#define	PCIX_COMMAND_MMRBC_MASK		0x000C
-#define	PCIX_COMMAND_MMRBC_SHIFT	0x2
-#define	PCIX_STATUS_HI_MMRBC_MASK	0x0060
-#define	PCIX_STATUS_HI_MMRBC_SHIFT	0x5
-#define	PCIX_STATUS_HI_MMRBC_4K		0x3
-#define	PCIX_STATUS_HI_MMRBC_2K		0x2
-#define	PCIX_STATUS_LO_FUNC_MASK	0x7
 #define	PCI_HEADER_TYPE_MULTIFUNC	0x80
 #define	PCIE_LINK_WIDTH_MASK		0x3F0
 #define	PCIE_LINK_WIDTH_SHIFT		4
+#define	PCIE_DEVICE_CONTROL2_16ms	0x0005
 
 #ifndef ETH_ADDR_LEN
 #define	ETH_ADDR_LEN			6
--- a/usr/src/uts/common/io/igb/igb_hw.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_hw.h	Sun Aug 16 19:52:03 2009 +0800
@@ -45,6 +45,8 @@
 #define	E1000_DEV_ID_82576_FIBER		0x10E6
 #define	E1000_DEV_ID_82576_SERDES		0x10E7
 #define	E1000_DEV_ID_82576_QUAD_COPPER		0x10E8
+#define	E1000_DEV_ID_82576_NS			0x150A
+#define	E1000_DEV_ID_82576_SERDES_QUAD		0x150D
 #define	E1000_DEV_ID_82575EB_COPPER		0x10A7
 #define	E1000_DEV_ID_82575EB_FIBER_SERDES	0x10A9
 #define	E1000_DEV_ID_82575GB_QUAD_COPPER	0x10D6
@@ -57,6 +59,8 @@
 
 #define	E1000_FUNC_0	0
 #define	E1000_FUNC_1	1
+#define	E1000_ALT_MAC_ADDRESS_OFFSET_LAN0	0
+#define	E1000_ALT_MAC_ADDRESS_OFFSET_LAN1	3
 
 enum e1000_mac_type {
 	e1000_undefined = 0,
@@ -166,6 +170,13 @@
 	e1000_smart_speed_off
 };
 
+enum e1000_serdes_link_state {
+	e1000_serdes_link_down = 0,
+	e1000_serdes_link_autoneg_progress,
+	e1000_serdes_link_autoneg_complete,
+	e1000_serdes_link_forced_up
+};
+
 /* Receive Descriptor */
 struct e1000_rx_desc {
 	__le64 buffer_addr; /* Address of the descriptor's data buffer */
@@ -436,6 +447,7 @@
 struct e1000_mac_operations {
 	/* Function pointers for the MAC. */
 	s32  (*init_params)(struct e1000_hw *);
+	s32  (*id_led_init)(struct e1000_hw *);
 	s32  (*blink_led)(struct e1000_hw *);
 	s32  (*check_for_link)(struct e1000_hw *);
 	bool (*check_mng_mode)(struct e1000_hw *hw);
@@ -443,10 +455,11 @@
 	void (*clear_hw_cntrs)(struct e1000_hw *);
 	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
+	void (*set_lan_id)(struct e1000_hw *);
 	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
 	s32  (*led_on)(struct e1000_hw *);
 	s32  (*led_off)(struct e1000_hw *);
-	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
+	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
 	s32  (*reset_hw)(struct e1000_hw *);
 	s32  (*init_hw)(struct e1000_hw *);
 	void (*shutdown_serdes)(struct e1000_hw *);
@@ -519,6 +532,10 @@
 	u16 ifs_ratio;
 	u16 ifs_step_size;
 	u16 mta_reg_count;
+
+	/* Maximum size of the MTA register table in all supported adapters */
+#define	MAX_MTA_REG 128
+	u32 mta_shadow[MAX_MTA_REG];
 	u16 rar_entry_count;
 
 	u8  forced_speed_duplex;
@@ -530,6 +547,7 @@
 	bool autoneg_failed;
 	bool get_link_status;
 	bool in_ifs_mode;
+	enum e1000_serdes_link_state serdes_link_state;
 	bool serdes_has_link;
 	bool tx_pkt_filtering;
 };
@@ -604,10 +622,12 @@
 
 struct e1000_dev_spec_82575 {
 	bool sgmii_active;
+	bool global_device_reset;
 };
 
 struct e1000_dev_spec_vf {
 	u32	vf_number;
+	u32	v2p_mailbox;
 };
 
 struct e1000_hw {
@@ -641,8 +661,7 @@
 
 /* These functions must be implemented by drivers */
 s32  e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
-void e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
-void e1000_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
+s32  e1000_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
 
 #ifdef __cplusplus
 }
--- a/usr/src/uts/common/io/igb/igb_mac.c	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_mac.c	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.92 v2008-10-7 */
+/* IntelVersion: 1.104 v2-9-8_2009-6-12 */
 
 #include "igb_api.h"
 
@@ -34,6 +34,7 @@
 static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw);
 static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw);
 static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw);
+static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw);
 
 /*
  * e1000_init_mac_ops_generic - Initialize MAC function pointers
@@ -53,6 +54,7 @@
 	mac->ops.reset_hw = e1000_null_ops_generic;
 	mac->ops.setup_physical_interface = e1000_null_ops_generic;
 	mac->ops.get_bus_info = e1000_null_ops_generic;
+	mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pcie;
 	mac->ops.read_mac_addr = e1000_read_mac_addr_generic;
 	mac->ops.config_collision_dist = e1000_config_collision_dist_generic;
 	mac->ops.clear_hw_cntrs = e1000_null_mac_generic;
@@ -133,10 +135,10 @@
  * @hw: pointer to the HW structure
  */
 void
-e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c)
+e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a)
 {
 	DEBUGFUNC("e1000_null_update_mc");
-	UNREFERENCED_5PARAMETER(hw, h, a, b, c);
+	UNREFERENCED_3PARAMETER(hw, h, a);
 }
 
 /*
@@ -173,67 +175,6 @@
 }
 
 /*
- * e1000_get_bus_info_pci_generic - Get PCI(x) bus information
- * @hw: pointer to the HW structure
- *
- * Determines and stores the system bus information for a particular
- * network interface.  The following bus information is determined and stored:
- * bus speed, bus width, type (PCI/PCIx), and PCI(-x) function.
- */
-s32
-e1000_get_bus_info_pci_generic(struct e1000_hw *hw)
-{
-	struct e1000_bus_info *bus = &hw->bus;
-	u32 status = E1000_READ_REG(hw, E1000_STATUS);
-	s32 ret_val = E1000_SUCCESS;
-	u16 pci_header_type;
-
-	DEBUGFUNC("e1000_get_bus_info_pci_generic");
-
-	/* PCI or PCI-X? */
-	bus->type = (status & E1000_STATUS_PCIX_MODE)
-	    ? e1000_bus_type_pcix
-	    : e1000_bus_type_pci;
-
-	/* Bus speed */
-	if (bus->type == e1000_bus_type_pci) {
-		bus->speed = (status & E1000_STATUS_PCI66)
-		    ? e1000_bus_speed_66
-		    : e1000_bus_speed_33;
-	} else {
-		switch (status & E1000_STATUS_PCIX_SPEED) {
-		case E1000_STATUS_PCIX_SPEED_66:
-			bus->speed = e1000_bus_speed_66;
-			break;
-		case E1000_STATUS_PCIX_SPEED_100:
-			bus->speed = e1000_bus_speed_100;
-			break;
-		case E1000_STATUS_PCIX_SPEED_133:
-			bus->speed = e1000_bus_speed_133;
-			break;
-		default:
-			bus->speed = e1000_bus_speed_reserved;
-			break;
-		}
-	}
-
-	/* Bus width */
-	bus->width = (status & E1000_STATUS_BUS64)
-	    ? e1000_bus_width_64
-	    : e1000_bus_width_32;
-
-	/* Which PCI(-X) function? */
-	e1000_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type);
-	if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC)
-		bus->func = (status & E1000_STATUS_FUNC_MASK)
-		    >> E1000_STATUS_FUNC_SHIFT;
-	else
-		bus->func = 0;
-
-	return (ret_val);
-}
-
-/*
  * e1000_get_bus_info_pcie_generic - Get PCIe bus information
  * @hw: pointer to the HW structure
  *
@@ -244,10 +185,10 @@
 s32
 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw)
 {
+	struct e1000_mac_info *mac = &hw->mac;
 	struct e1000_bus_info *bus = &hw->bus;
 	s32 ret_val;
-	u32 status;
-	u16 pcie_link_status, pci_header_type;
+	u16 pcie_link_status;
 
 	DEBUGFUNC("e1000_get_bus_info_pcie_generic");
 
@@ -262,19 +203,48 @@
 		bus->width = (enum e1000_bus_width)((pcie_link_status &
 		    PCIE_LINK_WIDTH_MASK) >> PCIE_LINK_WIDTH_SHIFT);
 
-	e1000_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type);
-	if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) {
-		status = E1000_READ_REG(hw, E1000_STATUS);
-		bus->func = (status & E1000_STATUS_FUNC_MASK)
-		    >> E1000_STATUS_FUNC_SHIFT;
-	} else {
-		bus->func = 0;
-	}
+	mac->ops.set_lan_id(hw);
 
 	return (E1000_SUCCESS);
 }
 
 /*
+ * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
+ *
+ * @hw: pointer to the HW structure
+ *
+ * Determines the LAN function id by reading memory-mapped registers
+ * and swaps the port value if requested.
+ */
+static void
+e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
+{
+	struct e1000_bus_info *bus = &hw->bus;
+	u32 reg;
+
+	/*
+	 * The status register reports the correct function number
+	 * for the device regardless of function swap state.
+	 */
+	reg = E1000_READ_REG(hw, E1000_STATUS);
+	bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;
+}
+
+/*
+ * e1000_set_lan_id_single_port - Set LAN id for a single port device
+ * @hw: pointer to the HW structure
+ *
+ * Sets the LAN function id to zero for a single port device.
+ */
+void
+e1000_set_lan_id_single_port(struct e1000_hw *hw)
+{
+	struct e1000_bus_info *bus = &hw->bus;
+
+	bus->func = 0;
+}
+
+/*
  * e1000_clear_vfta_generic - Clear VLAN filter table
  * @hw: pointer to the HW structure
  *
@@ -325,6 +295,7 @@
 e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count)
 {
 	u32 i;
+	u8 mac_addr[ETH_ADDR_LEN] = {0};
 
 	DEBUGFUNC("e1000_init_rx_addrs_generic");
 
@@ -335,12 +306,8 @@
 
 	/* Zero out the other (rar_entry_count - 1) receive addresses */
 	DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1);
-	for (i = 1; i < rar_count; i++) {
-		E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0);
-		E1000_WRITE_FLUSH(hw);
-		E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0);
-		E1000_WRITE_FLUSH(hw);
-	}
+	for (i = 1; i < rar_count; i++)
+		hw->mac.ops.rar_set(hw, mac_addr, i);
 }
 
 /*
@@ -350,9 +317,10 @@
  * Checks the nvm for an alternate MAC address.  An alternate MAC address
  * can be setup by pre-boot software and must be treated like a permanent
  * address and must override the actual permanent MAC address.  If an
- * alternate MAC address is found it is saved in the hw struct and
- * programmed into RAR0 and the function returns success, otherwise the
- * function returns an error.
+ * alternate MAC address is found it is programmed into RAR0, replacing
+ * the permanent address that was installed into RAR0 by the Si on reset.
+ * This function will return SUCCESS unless it encounters an error while
+ * reading the EEPROM.
  */
 s32
 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
@@ -372,13 +340,12 @@
 	}
 
 	if (nvm_alt_mac_addr_offset == 0xFFFF) {
-		ret_val = -(E1000_NOT_IMPLEMENTED);
+		/* There is no Alternate MAC Address */
 		goto out;
 	}
 
 	if (hw->bus.func == E1000_FUNC_1)
-		nvm_alt_mac_addr_offset += ETH_ADDR_LEN / sizeof (u16);
-
+		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
 	for (i = 0; i < ETH_ADDR_LEN; i += 2) {
 		offset = nvm_alt_mac_addr_offset + (i >> 1);
 		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
@@ -393,14 +360,16 @@
 
 	/* if multicast bit is set, the alternate address will not be used */
 	if (alt_mac_addr[0] & 0x01) {
-		ret_val = -(E1000_NOT_IMPLEMENTED);
+		DEBUGOUT("Ignoring Alternate Mac Address with MC bit set\n");
 		goto out;
 	}
 
-	for (i = 0; i < ETH_ADDR_LEN; i++)
-		hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i];
-
-	hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0);
+	/*
+	 * We have a valid alternate MAC address, and we want to treat it the
+	 * same as the normal permanent MAC address stored by the HW into the
+	 * RAR. Do this by mapping this address into RAR0.
+	 */
+	hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
 
 out:
 	return (ret_val);
@@ -436,8 +405,15 @@
 	if (rar_low || rar_high)
 		rar_high |= E1000_RAH_AV;
 
+	/*
+	 * Some bridges will combine consecutive 32-bit writes into
+	 * a single burst write, which will malfunction on some parts.
+	 * The flushes avoid this.
+	 */
 	E1000_WRITE_REG(hw, E1000_RAL(index), rar_low);
+	E1000_WRITE_FLUSH(hw);
 	E1000_WRITE_REG(hw, E1000_RAH(index), rar_high);
+	E1000_WRITE_FLUSH(hw);
 }
 
 /*
@@ -482,56 +458,37 @@
  * @hw: pointer to the HW structure
  * @mc_addr_list: array of multicast addresses to program
  * @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
  *
- * Updates the Receive Address Registers and Multicast Table Array.
+ * Updates the Multicast Table Array.
  * The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this.
  */
 void
 e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
-    u8 *mc_addr_list, u32 mc_addr_count,
-    u32 rar_used_count, u32 rar_count)
+    u8 *mc_addr_list, u32 mc_addr_count)
 {
-	u32 hash_value;
-	u32 i;
+	u32 hash_value, hash_bit, hash_reg;
+	int i;
 
 	DEBUGFUNC("e1000_update_mc_addr_list_generic");
 
-	/*
-	 * Load the first set of multicast addresses into the exact
-	 * filters (RAR).  If there are not enough to fill the RAR
-	 * array, clear the filters.
-	 */
-	for (i = rar_used_count; i < rar_count; i++) {
-		if (mc_addr_count) {
-			hw->mac.ops.rar_set(hw, mc_addr_list, i);
-			mc_addr_count--;
-			mc_addr_list += ETH_ADDR_LEN;
-		} else {
-			E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0);
-			E1000_WRITE_FLUSH(hw);
-			E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0);
-			E1000_WRITE_FLUSH(hw);
-		}
+	/* clear mta_shadow */
+	memset(&hw->mac.mta_shadow, 0, sizeof (hw->mac.mta_shadow));
+
+	/* update mta_shadow from mc_addr_list */
+	for (i = 0; (u32) i < mc_addr_count; i++) {
+		hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list);
+
+		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+		hash_bit = hash_value & 0x1F;
+
+		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
+		mc_addr_list += (ETH_ADDR_LEN);
 	}
 
-	/* Clear the old settings from the MTA */
-	DEBUGOUT("Clearing MTA\n");
-	for (i = 0; i < hw->mac.mta_reg_count; i++) {
-		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
-		E1000_WRITE_FLUSH(hw);
-	}
-
-	/* Load any remaining multicast addresses into the hash table. */
-	for (; mc_addr_count > 0; mc_addr_count--) {
-		hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list);
-		DEBUGOUT1("Hash value = 0x%03X\n", hash_value);
-		hw->mac.ops.mta_set(hw, hash_value);
-		mc_addr_list += ETH_ADDR_LEN;
-	}
+	/* replace the entire MTA table */
+	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
+		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
+	E1000_WRITE_FLUSH(hw);
 }
 
 /*
@@ -609,44 +566,6 @@
 }
 
 /*
- * e1000_pcix_mmrbc_workaround_generic - Fix incorrect MMRBC value
- * @hw: pointer to the HW structure
- *
- * In certain situations, a system BIOS may report that the PCIx maximum
- * memory read byte count (MMRBC) value is higher than than the actual
- * value. We check the PCIx command register with the current PCIx status
- * register.
- */
-void
-e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw)
-{
-	u16 cmd_mmrbc;
-	u16 pcix_cmd;
-	u16 pcix_stat_hi_word;
-	u16 stat_mmrbc;
-
-	DEBUGFUNC("e1000_pcix_mmrbc_workaround_generic");
-
-	/* Workaround for PCI-X issue when BIOS sets MMRBC incorrectly */
-	if (hw->bus.type != e1000_bus_type_pcix)
-		return;
-
-	e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd);
-	e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
-	cmd_mmrbc = (pcix_cmd & PCIX_COMMAND_MMRBC_MASK) >>
-	    PCIX_COMMAND_MMRBC_SHIFT;
-	stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
-	    PCIX_STATUS_HI_MMRBC_SHIFT;
-	if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
-		stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
-	if (cmd_mmrbc > stat_mmrbc) {
-		pcix_cmd &= ~PCIX_COMMAND_MMRBC_MASK;
-		pcix_cmd |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
-		e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd);
-	}
-}
-
-/*
  * e1000_clear_hw_cntrs_base_generic - Clear base hardware counters
  * @hw: pointer to the HW structure
  *
--- a/usr/src/uts/common/io/igb/igb_mac.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_mac.h	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.29 v2008-10-7 */
+/* IntelVersion: 1.32 v2-9-8_2009-6-12 */
 
 #ifndef	_IGB_MAC_H
 #define	_IGB_MAC_H
@@ -44,7 +44,7 @@
 s32  e1000_null_ops_generic(struct e1000_hw *hw);
 s32  e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
 bool e1000_null_mng_mode(struct e1000_hw *hw);
-void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c);
+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_mta_set(struct e1000_hw *hw, u32 a);
 void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a);
@@ -57,8 +57,8 @@
 s32  e1000_disable_pcie_master_generic(struct e1000_hw *hw);
 s32  e1000_force_mac_fc_generic(struct e1000_hw *hw);
 s32  e1000_get_auto_rd_done_generic(struct e1000_hw *hw);
-s32  e1000_get_bus_info_pci_generic(struct e1000_hw *hw);
 s32  e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);
+void e1000_set_lan_id_single_port(struct e1000_hw *hw);
 s32  e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
 s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
     u16 *duplex);
@@ -68,8 +68,7 @@
 s32  e1000_led_on_generic(struct e1000_hw *hw);
 s32  e1000_led_off_generic(struct e1000_hw *hw);
 void e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
-    u8 *mc_addr_list, u32 mc_addr_count,
-    u32 rar_used_count, u32 rar_count);
+    u8 *mc_addr_list, u32 mc_addr_count);
 s32  e1000_set_fc_watermarks_generic(struct e1000_hw *hw);
 s32  e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw);
 s32  e1000_setup_led_generic(struct e1000_hw *hw);
--- a/usr/src/uts/common/io/igb/igb_main.c	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_main.c	Sun Aug 16 19:52:03 2009 +0800
@@ -29,7 +29,7 @@
 #include "igb_sw.h"
 
 static char ident[] = "Intel 1Gb Ethernet";
-static char igb_version[] = "igb 1.1.7";
+static char igb_version[] = "igb 1.1.8";
 
 /*
  * Local function protoypes
@@ -2584,8 +2584,7 @@
 	/*
 	 * Update the multicase addresses to the MTA registers
 	 */
-	e1000_update_mc_addr_list(hw, mc_addr_list, mc_addr_count,
-	    igb->unicst_total, hw->mac.rar_entry_count);
+	e1000_update_mc_addr_list(hw, mc_addr_list, mc_addr_count);
 }
 
 /*
@@ -2680,7 +2679,7 @@
 	igb->rx_ring_size = igb_get_prop(igb, PROP_RX_RING_SIZE,
 	    MIN_RX_RING_SIZE, MAX_RX_RING_SIZE, DEFAULT_RX_RING_SIZE);
 
-	igb->mr_enable = igb_get_prop(igb, PROP_MR_ENABLE, 0, 1, 1);
+	igb->mr_enable = igb_get_prop(igb, PROP_MR_ENABLE, 0, 1, 0);
 	igb->num_rx_groups = igb_get_prop(igb, PROP_RX_GROUP_NUM,
 	    MIN_RX_GROUP_NUM, MAX_RX_GROUP_NUM, DEFAULT_RX_GROUP_NUM);
 	/*
--- a/usr/src/uts/common/io/igb/igb_manage.c	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_manage.c	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.27 v2008-10-7 */
+/* IntelVersion: 1.27 v2-9-8_2009-6-12 */
 
 #include "igb_api.h"
 
--- a/usr/src/uts/common/io/igb/igb_manage.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_manage.h	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.18 v2008-10-7 */
+/* IntelVersion: 1.18 v2-9-8_2009-6-12 */
 
 #ifndef _IGB_MANAGE_H
 #define	_IGB_MANAGE_H
--- a/usr/src/uts/common/io/igb/igb_nvm.c	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_nvm.c	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.46 v2008-10-7 */
+/* IntelVersion: 1.49 v2-9-8_2009-6-12 */
 
 #include "igb_api.h"
 
@@ -771,31 +771,23 @@
 s32
 e1000_read_mac_addr_generic(struct e1000_hw *hw)
 {
-	s32  ret_val = E1000_SUCCESS;
-	u16 offset, nvm_data, i;
-
-	DEBUGFUNC("e1000_read_mac_addr");
+	u32 rar_high;
+	u32 rar_low;
+	u16 i;
 
-	for (i = 0; i < ETH_ADDR_LEN; i += 2) {
-		offset = i >> 1;
-		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
-		if (ret_val) {
-			DEBUGOUT("NVM Read Error\n");
-			goto out;
-		}
-		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
-		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
-	}
+	rar_high = E1000_READ_REG(hw, E1000_RAH(0));
+	rar_low = E1000_READ_REG(hw, E1000_RAL(0));
 
-	/* Flip last bit of mac address if we're on second port */
-	if (hw->bus.func == E1000_FUNC_1)
-		hw->mac.perm_addr[5] ^= 1;
+	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
+		hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
+
+	for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
+		hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
 
 	for (i = 0; i < ETH_ADDR_LEN; i++)
 		hw->mac.addr[i] = hw->mac.perm_addr[i];
 
-out:
-	return (ret_val);
+	return (E1000_SUCCESS);
 }
 
 /*
--- a/usr/src/uts/common/io/igb/igb_nvm.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_nvm.h	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.18 v2008-10-7 */
+/* IntelVersion: 1.18 v2-9-8_2009-6-12 */
 
 #ifndef _IGB_NVM_H
 #define	_IGB_NVM_H
--- a/usr/src/uts/common/io/igb/igb_osdep.c	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_osdep.c	Sun Aug 16 19:52:03 2009 +0800
@@ -31,22 +31,6 @@
 
 
 void
-e1000_pci_set_mwi(struct e1000_hw *hw)
-{
-	uint16_t val = hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE;
-
-	e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val);
-}
-
-void
-e1000_pci_clear_mwi(struct e1000_hw *hw)
-{
-	uint16_t val = hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
-
-	e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val);
-}
-
-void
 e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
 {
 	pci_config_put16(OS_DEP(hw)->cfg_handle, reg, *value);
@@ -61,25 +45,50 @@
 
 /*
  * Return the 16-bit value from pci-e config space at offset reg into the pci-e
- * capability block.
+ * capability block.  Note that this refers to the pci-e capability block in
+ * standard pci config space, not the block in pci-e extended config space.
  */
 int32_t
 e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
 {
-	uint32_t pcie_cap = PCI_EX_CONF_CAP;	/* default */
+	uint8_t pcie_id = PCI_CAP_ID_PCI_E;
+	uint16_t pcie_cap;
+	int32_t status;
 
-	switch (hw->mac.type) {
-	case e1000_82575:
-		pcie_cap = 0xa0;
-		break;
-	case e1000_82576:
-		pcie_cap = 0xa0;
-		break;
+	/* locate the pci-e capability block */
+	status = pci_lcap_locate((OS_DEP(hw))->cfg_handle, pcie_id, &pcie_cap);
+	if (status == DDI_SUCCESS) {
+
+		/* read at given offset into block */
+		*value = pci_config_get16(OS_DEP(hw)->cfg_handle,
+		    (pcie_cap + reg));
 	}
 
-	*value = pci_config_get16(OS_DEP(hw)->cfg_handle, (pcie_cap + reg));
+	return (status);
+}
 
-	return (0);
+/*
+ * Write the given 16-bit value to pci-e config space at offset reg into the
+ * pci-e capability block.  Note that this refers to the pci-e capability block
+ * in standard pci config space, not the block in pci-e extended config space.
+ */
+int32_t
+e1000_write_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
+{
+	uint8_t pcie_id = PCI_CAP_ID_PCI_E;
+	uint16_t pcie_cap;
+	int32_t status;
+
+	/* locate the pci-e capability block */
+	status = pci_lcap_locate(OS_DEP(hw)->cfg_handle, pcie_id, &pcie_cap);
+	if (status == DDI_SUCCESS) {
+
+		/* write at given offset into block */
+		pci_config_put16(OS_DEP(hw)->cfg_handle,
+		    (off_t)(pcie_cap + reg), *value);
+	}
+
+	return (status);
 }
 
 /*
--- a/usr/src/uts/common/io/igb/igb_osdep.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_osdep.h	Sun Aug 16 19:52:03 2009 +0800
@@ -48,6 +48,7 @@
 #include <sys/dditypes.h>
 #include <sys/sunddi.h>
 #include <sys/pci.h>
+#include <sys/pci_cap.h>
 #include <sys/atomic.h>
 #include <sys/note.h>
 #include "igb_debug.h"
--- a/usr/src/uts/common/io/igb/igb_phy.c	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_phy.c	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.112 v2008-10-7 */
+/* IntelVersion: 1.140 v2-9-8_2009-6-12 */
 
 #include "igb_api.h"
 
@@ -1283,6 +1283,76 @@
 }
 
 /*
+ * e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
+ * @hw: pointer to the HW structure
+ *
+ * Forces the speed and duplex settings of the PHY.
+ * This is a function pointer entry point only called by
+ * PHY setup routines.
+ */
+s32
+e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 data;
+	bool link;
+
+	DEBUGFUNC("e1000_phy_force_speed_duplex_ife");
+
+	if (phy->type != e1000_phy_ife) {
+		ret_val = e1000_phy_force_speed_duplex_igp(hw);
+		goto out;
+	}
+
+	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data);
+	if (ret_val)
+		goto out;
+
+	e1000_phy_force_speed_duplex_setup(hw, &data);
+
+	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data);
+	if (ret_val)
+		goto out;
+
+	/* Disable MDI-X support for 10/100 */
+	ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
+	if (ret_val)
+		goto out;
+
+	data &= ~IFE_PMC_AUTO_MDIX;
+	data &= ~IFE_PMC_FORCE_MDIX;
+
+	ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data);
+	if (ret_val)
+		goto out;
+
+	DEBUGOUT1("IFE PMC: %X\n", data);
+
+	usec_delay(1);
+
+	if (phy->autoneg_wait_to_complete) {
+		DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n");
+
+		ret_val = e1000_phy_has_link_generic(hw,
+		    PHY_FORCE_LIMIT, 100000, &link);
+		if (ret_val)
+			goto out;
+
+		if (!link)
+			DEBUGOUT("Link taking longer than expected.\n");
+
+		/* Try once more */
+		ret_val = e1000_phy_has_link_generic(hw,
+		    PHY_FORCE_LIMIT, 100000, &link);
+		if (ret_val)
+			goto out;
+	}
+
+out:
+	return (ret_val);
+}
+/*
  * e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
  * @hw: pointer to the HW structure
  * @phy_ctrl: pointer to current value of PHY_CONTROL
@@ -1566,6 +1636,41 @@
 }
 
 /*
+ * e1000_check_polarity_ife - Check cable polarity for IFE PHY
+ * @hw: pointer to the HW structure
+ *
+ * Polarity is determined on the polarity reversal feature being enabled.
+ */
+s32
+e1000_check_polarity_ife(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 phy_data, offset, mask;
+
+	DEBUGFUNC("e1000_check_polarity_ife");
+
+	/*
+	 * Polarity is determined based on the reversal feature being enabled.
+	 */
+	if (phy->polarity_correction) {
+		offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
+		mask = IFE_PESC_POLARITY_REVERSED;
+	} else {
+		offset = IFE_PHY_SPECIAL_CONTROL;
+		mask = IFE_PSC_FORCE_POLARITY;
+	}
+
+	ret_val = phy->ops.read_reg(hw, offset, &phy_data);
+
+	if (!ret_val)
+		phy->cable_polarity = (phy_data & mask)
+		    ? e1000_rev_polarity_reversed
+		    : e1000_rev_polarity_normal;
+
+	return (ret_val);
+}
+/*
  * e1000_wait_autoneg_generic - Wait for auto-neg completion
  * @hw: pointer to the HW structure
  *
@@ -1631,9 +1736,16 @@
 		 * it across the board.
 		 */
 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
-		if (ret_val)
-			break;
-		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
+		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);
+			ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
+			    &phy_status);
+		}
 		if (ret_val)
 			break;
 		if (phy_status & MII_SR_LINK_STATUS)
@@ -1680,14 +1792,15 @@
 	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
 	    M88E1000_PSSR_CABLE_LENGTH_SHIFT;
 	if (index < (M88E1000_CABLE_LENGTH_TABLE_SIZE + 1)) {
-		phy->min_cable_length = e1000_m88_cable_length_table[index];
-		phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+		ret_val = E1000_ERR_PHY;
+		goto out;
+	}
 
-		phy->cable_length = (phy->min_cable_length +
-		    phy->max_cable_length) / 2;
-	} else {
-		ret_val = E1000_ERR_PHY;
-	}
+	phy->min_cable_length = e1000_m88_cable_length_table[index];
+	phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+
+	phy->cable_length = (phy->min_cable_length +
+	    phy->max_cable_length) / 2;
 
 out:
 	return (ret_val);
@@ -2140,6 +2253,48 @@
 }
 
 /*
+ * e1000_determine_phy_address - Determines PHY address.
+ * @hw: pointer to the HW structure
+ *
+ * This uses a trial and error method to loop through possible PHY
+ * addresses. It tests each by reading the PHY ID registers and
+ * checking for a match.
+ */
+s32
+e1000_determine_phy_address(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_PHY_TYPE;
+	u32 phy_addr = 0;
+	u32 i;
+	enum e1000_phy_type phy_type = e1000_phy_unknown;
+
+	hw->phy.id = phy_type;
+
+	for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
+		hw->phy.addr = phy_addr;
+		i = 0;
+
+		do {
+			e1000_get_phy_id(hw);
+			phy_type = e1000_get_phy_type_from_id(hw->phy.id);
+
+			/*
+			 * If phy_type is valid, break - we found our
+			 * PHY address
+			 */
+			if (phy_type  != e1000_phy_unknown) {
+				ret_val = E1000_SUCCESS;
+				goto out;
+			}
+			msec_delay(1);
+			i++;
+		} while (i < 10);
+	}
+
+out:
+	return (ret_val);
+}
+/*
  * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
  * @hw: pointer to the HW structure
  *
--- a/usr/src/uts/common/io/igb/igb_phy.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_phy.h	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.55 v2008-10-7 */
+/* IntelVersion: 1.69 v2-9-8_2009-6-12 */
 
 #ifndef _IGB_PHY_H
 #define	_IGB_PHY_H
@@ -43,12 +43,14 @@
 s32 e1000_check_downshift_generic(struct e1000_hw *hw);
 s32 e1000_check_polarity_m88(struct e1000_hw *hw);
 s32 e1000_check_polarity_igp(struct e1000_hw *hw);
+s32 e1000_check_polarity_ife(struct e1000_hw *hw);
 s32 e1000_check_reset_block_generic(struct e1000_hw *hw);
 s32 e1000_copper_link_autoneg(struct e1000_hw *hw);
 s32 e1000_copper_link_setup_igp(struct e1000_hw *hw);
 s32 e1000_copper_link_setup_m88(struct e1000_hw *hw);
 s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw);
 s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw);
+s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
 s32 e1000_get_cable_length_m88(struct e1000_hw *hw);
 s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw);
 s32 e1000_get_cfg_done_generic(struct e1000_hw *hw);
@@ -73,6 +75,7 @@
     u32 usec_interval, bool *success);
 s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
 enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
+s32 e1000_determine_phy_address(struct e1000_hw *hw);
 void e1000_power_up_phy_copper(struct e1000_hw *hw);
 void e1000_power_down_phy_copper(struct e1000_hw *hw);
 s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
@@ -112,7 +115,7 @@
 #define	IGP01E1000_PLHR_SS_DOWNGRADE	0x8000
 
 #define	IGP01E1000_PSSR_POLARITY_REVERSED	0x0002
-#define	IGP01E1000_PSSR_MDIX			0x0008
+#define	IGP01E1000_PSSR_MDIX			0x0800
 #define	IGP01E1000_PSSR_SPEED_MASK		0xC000
 #define	IGP01E1000_PSSR_SPEED_1000MBPS		0xC000
 
@@ -135,6 +138,8 @@
 #define	E1000_KMRNCTRLSTA_OFFSET_SHIFT	16
 #define	E1000_KMRNCTRLSTA_REN		0x00200000
 #define	E1000_KMRNCTRLSTA_DIAG_OFFSET	0x3	/* Kumeran Diagnostic */
+#define	E1000_KMRNCTRLSTA_TIMEOUTS	0x4	/* Kumeran Timeouts */
+#define	E1000_KMRNCTRLSTA_INBAND_PARAM	0x9	/* Kumeran InBand Parameters */
 #define	E1000_KMRNCTRLSTA_DIAG_NELPBK	0x1000	/* Nearend Loopback mode */
 
 #define	IFE_PHY_EXTENDED_STATUS_CONTROL	0x10
--- a/usr/src/uts/common/io/igb/igb_regs.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_regs.h	Sun Aug 16 19:52:03 2009 +0800
@@ -26,7 +26,7 @@
  * Use is subject to license terms of the CDDL.
  */
 
-/* IntelVersion: 1.61 v2008-10-7 */
+/* IntelVersion: 1.70 v2-9-8_2009-6-12 */
 
 #ifndef _IGB_REGS_H
 #define	_IGB_REGS_H
@@ -426,6 +426,7 @@
 #define	E1000_GIOCTL		0x05B44 /* GIO Analog Control Register */
 #define	E1000_SCCTL		0x05B4C /* PCIc PLL Configuration Register */
 #define	E1000_GCR		0x05B00 /* PCI-Ex Control */
+#define	E1000_GCR2		0x05B64 /* PCI-Ex Control #2 */
 #define	E1000_GSCL_1		0x05B10 /* PCI-Ex Statistic Control #1 */
 #define	E1000_GSCL_2		0x05B14 /* PCI-Ex Statistic Control #2 */
 #define	E1000_GSCL_3		0x05B18 /* PCI-Ex Statistic Control #3 */
@@ -434,6 +435,8 @@
 #define	E1000_FACTPS		0x05B30
 #define	E1000_SWSM		0x05B50 /* SW Semaphore */
 #define	E1000_FWSM		0x05B54 /* FW Semaphore */
+/* Driver-only SW semaphore (not used by BOOT agents) */
+#define	E1000_SWSM2		0x05B58
 #define	E1000_DCA_ID		0x05B70 /* DCA Requester ID Information - RO */
 #define	E1000_DCA_CTRL		0x05B74 /* DCA Control - RW */
 #define	E1000_FFLT_DBG		0x05F04 /* Debug Register */
@@ -472,7 +475,6 @@
 #define	E1000_VFTE	0x00C90 /* VF Transmit Enables */
 #define	E1000_QDE	0x02408 /* Queue Drop Enable - RW */
 #define	E1000_DTXSWC	0x03500 /* DMA Tx Switch Control - RW */
-#define	E1000_VLVF	0x05D00 /* VLAN Virtual Machine Filter - RW */
 #define	E1000_RPLOLR	0x05AF0 /* Replication Offload - RW */
 #define	E1000_UTA	0x0A000 /* Unicast Table Array - RW */
 #define	E1000_IOVTCL	0x05BBC /* IOV Control Register */
@@ -483,12 +485,15 @@
 #define	E1000_VMBMEM(_n)	(0x00800 + (64 * (_n)))
 #define	E1000_VFVMBMEM(_n)	(0x00800 + (_n))
 #define	E1000_VMOLR(_n)		(0x05AD0 + (4 * (_n)))
+/* VLAN Virtual Machine Filter - RW */
+#define	E1000_VLVF(_n)		(0x05D00 + (4 * (_n)))
 
 /* Filtering Registers */
 #define	E1000_SAQF(_n)	(0x05980 + (4 * (_n))) /* Source Address Queue Fltr */
 #define	E1000_DAQF(_n)	(0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */
 #define	E1000_SPQF(_n)	(0x059C0 + (4 * (_n))) /* Source Port Queue Fltr */
 #define	E1000_FTQF(_n)	(0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */
+#define	E1000_TTQF(_n)	(0x059E0 + (4 * (_n))) /* 2-tuple Queue Fltr */
 #define	E1000_SYNQF(_n)	(0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
 #define	E1000_ETQF(_n)	(0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
 
--- a/usr/src/uts/common/io/igb/igb_sw.h	Sun Aug 16 16:01:00 2009 +0800
+++ b/usr/src/uts/common/io/igb/igb_sw.h	Sun Aug 16 19:52:03 2009 +0800
@@ -830,6 +830,10 @@
 /*
  * Function prototypes in e1000_osdep.c
  */
+void e1000_write_pci_cfg(struct e1000_hw *, uint32_t, uint16_t *);
+void e1000_read_pci_cfg(struct e1000_hw *, uint32_t, uint16_t *);
+int32_t e1000_read_pcie_cap_reg(struct e1000_hw *, uint32_t, uint16_t *);
+int32_t e1000_write_pcie_cap_reg(struct e1000_hw *, uint32_t, uint16_t *);
 void e1000_rar_clear(struct e1000_hw *hw, uint32_t);
 void e1000_rar_set_vmdq(struct e1000_hw *hw, const uint8_t *, uint32_t,
     uint32_t, uint8_t);