6708311 ixgbe needs to support the new device Niantic
authorBin Tu - Sun Microsystems - Beijing China <Samuel.Tu@Sun.COM>
Sun, 12 Apr 2009 18:46:02 +0800
changeset 9353 b9caf92a0042
parent 9352 a4f5bee2dbad
child 9354 9559ac454e7e
6708311 ixgbe needs to support the new device Niantic 6764528 ixgbe should not reserve a msix vector for link change 6774000 ixgbe IPHDR_ALIGN_ROOM code can be revised 6804557 The ixgbe driver can generate fma IO Service Restored ereports without any service-lost reports
usr/src/pkgdefs/SUNWixgbe/postinstall
usr/src/uts/common/Makefile.files
usr/src/uts/common/io/ixgbe/ixgbe_82598.c
usr/src/uts/common/io/ixgbe/ixgbe_82599.c
usr/src/uts/common/io/ixgbe/ixgbe_api.c
usr/src/uts/common/io/ixgbe/ixgbe_api.h
usr/src/uts/common/io/ixgbe/ixgbe_buf.c
usr/src/uts/common/io/ixgbe/ixgbe_common.c
usr/src/uts/common/io/ixgbe/ixgbe_common.h
usr/src/uts/common/io/ixgbe/ixgbe_debug.c
usr/src/uts/common/io/ixgbe/ixgbe_debug.h
usr/src/uts/common/io/ixgbe/ixgbe_gld.c
usr/src/uts/common/io/ixgbe/ixgbe_main.c
usr/src/uts/common/io/ixgbe/ixgbe_osdep.c
usr/src/uts/common/io/ixgbe/ixgbe_osdep.h
usr/src/uts/common/io/ixgbe/ixgbe_phy.c
usr/src/uts/common/io/ixgbe/ixgbe_phy.h
usr/src/uts/common/io/ixgbe/ixgbe_rx.c
usr/src/uts/common/io/ixgbe/ixgbe_stat.c
usr/src/uts/common/io/ixgbe/ixgbe_sw.h
usr/src/uts/common/io/ixgbe/ixgbe_tx.c
usr/src/uts/common/io/ixgbe/ixgbe_type.h
--- a/usr/src/pkgdefs/SUNWixgbe/postinstall	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/pkgdefs/SUNWixgbe/postinstall	Sun Apr 12 18:46:02 2009 +0800
@@ -2,7 +2,7 @@
 #
 # CDDL HEADER START
 #
-# Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+# Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
 # The contents of this file are subject to the terms of the
 # Common Development and Distribution License (the "License").
 # You may not use this file except in compliance with the License.
@@ -128,13 +128,20 @@
 }
 
 check_add_drv -i		\
-	'"pciex8086,10c6"
+	'"pciex8086,10b6"
+	"pciex8086,10c6"
 	"pciex8086,10c7"
 	"pciex8086,10c8"
 	"pciex8086,10db"
 	"pciex8086,10dd"
+	"pciex8086,10e1"
 	"pciex8086,10ec"
-	"pciex8086,10e1"
 	"pciex8086,10f1"
-	"pciex8086,10f4"'	\
+	"pciex8086,10f4"
+	"pciex8086,10f7"
+	"pciex8086,10f9"
+	"pciex8086,10fb"
+	"pciex8086,1507"
+	"pciex8086,1508"
+	"pciex8086,1514"'	\
 	-b "$BASEDIR" ixgbe
--- a/usr/src/uts/common/Makefile.files	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/Makefile.files	Sun Apr 12 18:46:02 2009 +0800
@@ -1750,8 +1750,8 @@
 #
 #       Intel 10GbE PCIE NIC driver module
 #
-IXGBE_OBJS =    ixgbe_82598.o ixgbe_api.o ixgbe_common.o        \
-                ixgbe_phy.o                                     \
+IXGBE_OBJS =    ixgbe_82598.o ixgbe_82599.o ixgbe_api.o		\
+                ixgbe_common.o ixgbe_phy.o			\
                 ixgbe_buf.o ixgbe_debug.o ixgbe_gld.o           \
                 ixgbe_log.o ixgbe_main.o ixgbe_ndd.o            \
                 ixgbe_osdep.o ixgbe_rx.o ixgbe_stat.o           \
--- a/usr/src/uts/common/io/ixgbe/ixgbe_82598.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_82598.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,24 +23,21 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
-/* IntelVersion: 1.112 v2008-09-12 */
+/* IntelVersion: 1.138 v2-7-8_2009-4-7 */
 
 #include "ixgbe_type.h"
 #include "ixgbe_api.h"
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
-#ident "$Id: ixgbe_82598.c,v 1.112 2008/09/03 21:16:55 mrchilak Exp $"
 
 s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw);
 static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
     ixgbe_link_speed *speed, bool *autoneg);
-s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
-    ixgbe_link_speed *speed, bool *autoneg);
 static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
-s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num);
+s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num);
 static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw);
 static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
     ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete);
@@ -56,13 +53,38 @@
 s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan,
     u32 vind, bool vlan_on);
 static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index);
-static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index);
 s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val);
 s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val);
 s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
     u8 *eeprom_data);
-s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw);
+u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw);
+s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw);
+
+/*
+ * ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count
+ * @hw: pointer to hardware structure
+ *
+ * Read PCIe configuration space, and get the MSI-X vector count from
+ * the capabilities table.
+ */
+u32
+ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
+{
+	u32 msix_count = 18;
+
+	if (hw->mac.msix_vectors_from_pcie) {
+		msix_count = IXGBE_READ_PCIE_WORD(hw,
+		    IXGBE_PCIE_MSIX_82598_CAPS);
+		msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+
+		/*
+		 * MSI-X count is zero-based in HW, so increment to give
+		 * proper value
+		 */
+		msix_count++;
+	}
+	return (msix_count);
+}
 
 /*
  * ixgbe_init_ops_82598 - Inits func ptrs and MAC type
@@ -76,11 +98,13 @@
 {
 	struct ixgbe_mac_info *mac = &hw->mac;
 	struct ixgbe_phy_info *phy = &hw->phy;
-	s32 ret_val = 0;
-	u16 list_offset, data_offset;
+	s32 ret_val;
 
-	(void) ixgbe_init_phy_ops_generic(hw);
-	(void) ixgbe_init_ops_generic(hw);
+	ret_val = ixgbe_init_phy_ops_generic(hw);
+	ret_val = ixgbe_init_ops_generic(hw);
+
+	/* PHY */
+	phy->ops.init = &ixgbe_init_phy_ops_82598;
 
 	/* MAC */
 	mac->ops.reset_hw = &ixgbe_reset_hw_82598;
@@ -90,10 +114,6 @@
 	mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82598;
 	mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82598;
 
-	/* LEDs */
-	mac->ops.blink_led_start = &ixgbe_blink_led_start_82598;
-	mac->ops.blink_led_stop = &ixgbe_blink_led_stop_82598;
-
 	/* RAR, Multicast, VLAN */
 	mac->ops.set_vmdq = &ixgbe_set_vmdq_82598;
 	mac->ops.clear_vmdq = &ixgbe_clear_vmdq_82598;
@@ -101,36 +121,63 @@
 	mac->ops.clear_vfta = &ixgbe_clear_vfta_82598;
 
 	/* Flow Control */
-	mac->ops.setup_fc = &ixgbe_setup_fc_82598;
-
-	/* Link */
-	mac->ops.check_link = &ixgbe_check_mac_link_82598;
-	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
-		mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
-		mac->ops.setup_link_speed =
-		    &ixgbe_setup_copper_link_speed_82598;
-		mac->ops.get_link_capabilities =
-		    &ixgbe_get_copper_link_capabilities_82598;
-	} else {
-		mac->ops.setup_link = &ixgbe_setup_mac_link_82598;
-		mac->ops.setup_link_speed = &ixgbe_setup_mac_link_speed_82598;
-		mac->ops.get_link_capabilities =
-		    &ixgbe_get_link_capabilities_82598;
-	}
+	mac->ops.fc_enable = &ixgbe_fc_enable_82598;
 
 	mac->mcft_size = 128;
 	mac->vft_size = 128;
 	mac->num_rar_entries = 16;
 	mac->max_tx_queues = 32;
 	mac->max_rx_queues = 64;
+	mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
 
 	/* SFP+ Module */
 	phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598;
 
-	/* Call PHY identify routine to get the phy type */
+	/*
+	 * Call PHY identify routine to assign the phy type for PHY init
+	 * and media type determination
+	 */
 	phy->ops.identify(hw);
 
-	/* PHY Init */
+	/* Link */
+	mac->ops.check_link = &ixgbe_check_mac_link_82598;
+	mac->ops.setup_link = &ixgbe_setup_mac_link_82598;
+	mac->ops.setup_link_speed = &ixgbe_setup_mac_link_speed_82598;
+	mac->ops.get_link_capabilities =
+	    &ixgbe_get_link_capabilities_82598;
+
+	return (ret_val);
+}
+
+/*
+ * ixgbe_init_phy_ops_82598 - PHY/SFP specific init
+ * @hw: pointer to hardware structure
+ *
+ * Initialize any function pointers that were not able to be
+ * set during init_shared_code because the PHY/SFP type was
+ * not known.  Perform the SFP init if necessary.
+ *
+ */
+s32
+ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mac_info *mac = &hw->mac;
+	struct ixgbe_phy_info *phy = &hw->phy;
+	s32 ret_val = IXGBE_SUCCESS;
+	u16 list_offset, data_offset;
+
+	/* Identify the PHY */
+	phy->ops.identify(hw);
+
+	/* Overwrite the link function pointers if copper PHY */
+	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+		mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
+		mac->ops.setup_link_speed =
+		    &ixgbe_setup_copper_link_speed_82598;
+		mac->ops.get_link_capabilities =
+		    &ixgbe_get_copper_link_capabilities_generic;
+	}
+
 	switch (hw->phy.type) {
 	case ixgbe_phy_tn:
 		phy->ops.check_link = &ixgbe_check_phy_link_tnx;
@@ -177,18 +224,19 @@
     ixgbe_link_speed *speed, bool *autoneg)
 {
 	s32 status = IXGBE_SUCCESS;
-	s32 autoc_reg;
-
-	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 autoc = 0;
 
-	if (hw->mac.link_settings_loaded) {
-		autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
-		autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
-		autoc_reg |= hw->mac.link_attach_type;
-		autoc_reg |= hw->mac.link_mode_select;
-	}
+	/*
+	 * Determine link capabilities based on the stored value of AUTOC,
+	 * which represents EEPROM defaults.  If AUTOC value has not been
+	 * stored, use the current register value.
+	 */
+	if (hw->mac.orig_link_settings_stored)
+		autoc = hw->mac.orig_autoc;
+	else
+		autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
 
-	switch (autoc_reg & IXGBE_AUTOC_LMS_MASK) {
+	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
 		*autoneg = false;
@@ -207,9 +255,9 @@
 	case IXGBE_AUTOC_LMS_KX4_AN:
 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
-		if (autoc_reg & IXGBE_AUTOC_KX4_SUPP)
+		if (autoc & IXGBE_AUTOC_KX4_SUPP)
 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
-		if (autoc_reg & IXGBE_AUTOC_KX_SUPP)
+		if (autoc & IXGBE_AUTOC_KX_SUPP)
 			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
 		*autoneg = true;
 		break;
@@ -223,37 +271,6 @@
 }
 
 /*
- * ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @autoneg: boolean auto-negotiation value
- *
- * Determines the link capabilities by reading the AUTOC register.
- */
-s32
-ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
-    ixgbe_link_speed *speed, bool *autoneg)
-{
-	s32 status = IXGBE_ERR_LINK_SETUP;
-	u16 speed_ability;
-
-	*speed = 0;
-	*autoneg = true;
-
-	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
-	    IXGBE_MDIO_PMA_PMD_DEV_TYPE, &speed_ability);
-
-	if (status == IXGBE_SUCCESS) {
-		if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
-			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
-		if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
-			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
-	}
-
-	return (status);
-}
-
-/*
  * ixgbe_get_media_type_82598 - Determines media type
  * @hw: pointer to hardware structure
  *
@@ -264,8 +281,20 @@
 {
 	enum ixgbe_media_type media_type;
 
+	/* Detect if there is a copper PHY attached. */
+	if (hw->phy.type == ixgbe_phy_cu_unknown ||
+	    hw->phy.type == ixgbe_phy_tn) {
+		media_type = ixgbe_media_type_copper;
+		goto out;
+	}
+
 	/* Media type for I82598 is based on device ID */
 	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82598:
+	case IXGBE_DEV_ID_82598_BX:
+		/* Default device ID is mezzanine card KX/KX4 */
+		media_type = ixgbe_media_type_backplane;
+		break;
 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
 	case IXGBE_DEV_ID_82598EB_CX4:
@@ -283,112 +312,92 @@
 		media_type = ixgbe_media_type_unknown;
 		break;
 	}
-
+out:
 	return (media_type);
 }
 
 /*
- * ixgbe_setup_fc_82598 - Configure flow control settings
+ * ixgbe_fc_enable_82598 - Enable flow control
  * @hw: pointer to hardware structure
  * @packetbuf_num: packet buffer number (0-7)
  *
- * Configures the flow control settings based on SW configuration.  This
- * function is used for 802.3x flow control configuration only.
+ * Enable flow control according to the current settings.
  */
 s32
-ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
 {
-	u32 frctl_reg;
+	s32 ret_val = IXGBE_SUCCESS;
+	u32 fctrl_reg;
 	u32 rmcs_reg;
+	u32 reg;
+
+	DEBUGFUNC("ixgbe_fc_enable_82598");
 
-	if (packetbuf_num < 0 || packetbuf_num > 7) {
-		DEBUGOUT1("Invalid packet buffer number [%d], expected range is"
-		    " 0-7\n", packetbuf_num);
-		ASSERT(0);
-	}
+	/* Negotiate the fc mode to use */
+	ret_val = ixgbe_fc_autoneg(hw);
+	if (ret_val)
+		goto out;
 
-	frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-	frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
+	/* Disable any previous flow control settings */
+	fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+	fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
 
 	rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
 	rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
 
 	/*
-	 * 10 gig parts do not have a word in the EEPROM to determine the
-	 * default flow control setting, so we explicitly set it to full.
-	 */
-	if (hw->fc.type == ixgbe_fc_default)
-		hw->fc.type = ixgbe_fc_full;
-
-	/*
-	 * We want to save off the original Flow Control configuration just in
-	 * case we get disconnected and then reconnected into a different hub
-	 * or switch with different Flow Control capabilities.
-	 */
-	hw->fc.original_type = hw->fc.type;
-
-	/*
-	 * The possible values of the "flow_control" parameter are:
+	 * The possible values of fc.current_mode are:
 	 * 0: Flow control is completely disabled
-	 * 1: Rx flow control is enabled (we can receive pause frames but not
-	 *    send pause frames).
-	 * 2: Tx flow control is enabled (we can send pause frames but we do not
-	 *    support receiving pause frames)
+	 * 1: Rx flow control is enabled (we can receive pause frames,
+	 *    but not send pause frames).
+	 * 2: Tx flow control is enabled (we can send pause frames but
+	 *    we do not support receiving pause frames).
 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
 	 * other: Invalid.
 	 */
-	switch (hw->fc.type) {
+	switch (hw->fc.current_mode) {
 	case ixgbe_fc_none:
+		/*
+		 * Flow control is disabled by software override or autoneg.
+		 * The code below will actually disable it in the HW.
+		 */
 		break;
 	case ixgbe_fc_rx_pause:
 		/*
-		 * Rx Flow control is enabled,
-		 * and Tx Flow control is disabled.
+		 * Rx Flow control is enabled and Tx Flow control is
+		 * disabled by software override. Since there really
+		 * isn't a way to advertise that we are capable of RX
+		 * Pause ONLY, we will advertise that we support both
+		 * symmetric and asymmetric Rx PAUSE.  Later, we will
+		 * disable the adapter's ability to send PAUSE frames.
 		 */
-		frctl_reg |= IXGBE_FCTRL_RFCE;
+		fctrl_reg |= IXGBE_FCTRL_RFCE;
 		break;
 	case ixgbe_fc_tx_pause:
 		/*
-		 * Tx Flow control is enabled, and Rx Flow control is disabled,
-		 * by a software over-ride.
+		 * Tx Flow control is enabled, and Rx Flow control is
+		 * disabled by software override.
 		 */
 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
 		break;
 	case ixgbe_fc_full:
-		/*
-		 * Flow control (both Rx and Tx) is enabled by a software
-		 * over-ride.
-		 */
-		frctl_reg |= IXGBE_FCTRL_RFCE;
+		/* Flow control (both Rx and Tx) is enabled by SW override. */
+		fctrl_reg |= IXGBE_FCTRL_RFCE;
 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
 		break;
 	default:
-		/* We should never get here.  The value should be 0-3. */
 		DEBUGOUT("Flow control param set incorrectly\n");
-		ASSERT(0);
-		break;
+		ret_val = -IXGBE_ERR_CONFIG;
+		goto out;
 	}
 
-	/* Enable 802.3x based flow control settings. */
-	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
+	/* Set 802.3x based flow control settings. */
+	fctrl_reg |= IXGBE_FCTRL_DPF;
+	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
 
-	/*
-	 * Check for invalid software configuration, zeros are completely
-	 * invalid for all parameters used past this point, and if we enable
-	 * flow control with zero water marks, we blast flow control packets.
-	 */
-	if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
-		DEBUGOUT("Flow control structure initialized incorrectly\n");
-		return (IXGBE_ERR_INVALID_LINK_SETTINGS);
-	}
-
-	/*
-	 * We need to set up the Receive Threshold high and low water
-	 * marks as well as (optionally) enabling the transmission of
-	 * XON frames.
-	 */
-	if (hw->fc.type & ixgbe_fc_tx_pause) {
+	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
+	if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
 		if (hw->fc.send_xon) {
 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
 			    (hw->fc.low_water | IXGBE_FCRTL_XONE));
@@ -396,14 +405,23 @@
 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
 			    hw->fc.low_water);
 		}
+
 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
-		    (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
+		    (hw->fc.high_water | IXGBE_FCRTH_FCEN));
 	}
 
-	IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
+	/* Configure pause time (2 TCs per register) */
+	reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+	if ((packetbuf_num & 1) == 0)
+		reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
+	else
+		reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
+	IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+
 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
 
-	return (IXGBE_SUCCESS);
+out:
+	return (ret_val);
 }
 
 /*
@@ -421,27 +439,17 @@
 	u32 i;
 	s32 status = IXGBE_SUCCESS;
 
+	/* Restart link */
 	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-
-	if (hw->mac.link_settings_loaded) {
-		autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
-		autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
-		autoc_reg |= hw->mac.link_attach_type;
-		autoc_reg |= hw->mac.link_mode_select;
-
-		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-		IXGBE_WRITE_FLUSH(hw);
-		msec_delay(50);
-	}
-
-	/* Restart link */
 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
 
 	/* Only poll for autoneg to complete if specified to do so */
 	if (hw->phy.autoneg_wait_to_complete) {
-		if (hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN ||
-		    hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
+		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		    IXGBE_AUTOC_LMS_KX4_AN ||
+		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		    IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
 			links_reg = 0; /* Just in case Autoneg time = 0 */
 			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
 				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
@@ -456,14 +464,6 @@
 		}
 	}
 
-	/*
-	 * We want to save off the original Flow Control configuration just in
-	 * case we get disconnected and then reconnected into a different hub
-	 * or switch with different Flow Control capabilities.
-	 */
-	hw->fc.original_type = hw->fc.type;
-	(void) ixgbe_setup_fc_82598(hw, 0);
-
 	/* Add delay to filter out noises during initial link setup */
 	msec_delay(50);
 
@@ -474,7 +474,8 @@
  * ixgbe_check_mac_link_82598 - Get link/speed status
  * @hw: pointer to hardware structure
  * @speed: pointer to link speed
- * @link_up: TRUE is link is up, FALSE otherwise
+ * @link_up: true is link is up, false otherwise
+ * @link_up_wait_to_complete: bool used to wait for link up or not
  *
  * Reads the links register to determine if link is up and the current speed
  */
@@ -548,6 +549,11 @@
 	else
 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
 
+	/* if link is down, zero out the current_mode */
+	if (*link_up == false) {
+		hw->fc.current_mode = ixgbe_fc_none;
+		hw->fc.fc_was_autonegged = false;
+	}
 out:
 	return (IXGBE_SUCCESS);
 }
@@ -556,8 +562,8 @@
  * ixgbe_setup_mac_link_speed_82598 - Set MAC link speed
  * @hw: pointer to hardware structure
  * @speed: new link speed
- * @autoneg: TRUE if auto-negotiation enabled
- * @autoneg_wait_to_complete: TRUE if waiting is needed to complete
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
  *
  * Set the link speed in the AUTOC register and restarts link.
  */
@@ -567,33 +573,38 @@
     bool autoneg_wait_to_complete)
 {
 	s32 status = IXGBE_SUCCESS;
+	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+	u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 autoc = curr_autoc;
+	u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
 
-	/* If speed is 10G, then check for CX4 or XAUI. */
-	if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
-	    (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) {
-		hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
-	} else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) {
-		hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
-	} else if (autoneg) {
-		/* BX mode - Autonegotiate 1G */
-		if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD))
-			hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN;
-		else /* KX/KX4 mode */
-			hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN_1G_AN;
-	} else {
+	/* Check to see if speed passed in is supported. */
+	(void) ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
+	speed &= link_capabilities;
+
+	if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
 		status = IXGBE_ERR_LINK_SETUP;
+	} else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
+	    link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
+		/* Set KX4/KX support according to speed requested */
+		autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
+		if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+			autoc |= IXGBE_AUTOC_KX4_SUPP;
+		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+			autoc |= IXGBE_AUTOC_KX_SUPP;
+		if (autoc != curr_autoc)
+			IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
 	}
 
 	if (status == IXGBE_SUCCESS) {
 		hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete;
 
-		hw->mac.link_settings_loaded = true;
 		/*
 		 * Setup and restart the link based on the new values in
 		 * ixgbe_hw This will write the AUTOC register based on the new
 		 * stored values
 		 */
-		(void) ixgbe_setup_mac_link_82598(hw);
+		status = ixgbe_setup_mac_link_82598(hw);
 	}
 
 	return (status);
@@ -617,10 +628,6 @@
 	/* Restart autonegotiation on PHY */
 	status = hw->phy.ops.setup_link(hw);
 
-	/* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
-	hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
-	hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
-
 	/* Set up MAC */
 	(void) ixgbe_setup_mac_link_82598(hw);
 
@@ -631,8 +638,8 @@
  * ixgbe_setup_copper_link_speed_82598 - Set the PHY autoneg advertised field
  * @hw: pointer to hardware structure
  * @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
- * @autoneg_wait_to_complete: TRUE if waiting is needed to complete
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true if waiting is needed to complete
  *
  * Sets the link speed in the AUTOC register in the MAC and restarts link.
  */
@@ -648,10 +655,6 @@
 	status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
 	    autoneg_wait_to_complete);
 
-	/* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
-	hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
-	hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
-
 	/* Set up MAC */
 	(void) ixgbe_setup_mac_link_82598(hw);
 
@@ -713,14 +716,23 @@
 	}
 
 	/* Reset PHY */
-	if (hw->phy.reset_disable == false)
+	if (hw->phy.reset_disable == false) {
+		/* PHY ops must be identified and initialized prior to reset */
+
+		/* Init PHY and function pointers, perform SFP setup */
+		status = hw->phy.ops.init(hw);
+		/* Do not return error if SFP module is not supported. */
+		status = IXGBE_SUCCESS;
+
 		hw->phy.ops.reset(hw);
+	}
 
 	/*
 	 * Prevent the PCI-E bus from from hanging by disabling PCI-E master
 	 * access and verify no pending requests before reset
 	 */
-	if (ixgbe_disable_pcie_master(hw) != IXGBE_SUCCESS) {
+	status = ixgbe_disable_pcie_master(hw);
+	if (status != IXGBE_SUCCESS) {
 		status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
 	}
@@ -752,26 +764,24 @@
 	IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
 
 	/*
-	 * AUTOC register which stores link settings gets cleared
-	 * and reloaded from EEPROM after reset. We need to restore
-	 * our stored value from init in case SW changed the attach
-	 * type or speed.  If this is the first time and link settings
-	 * have not been stored, store default settings from AUTOC.
+	 * Store the original AUTOC value if it has not been
+	 * stored off yet.  Otherwise restore the stored original
+	 * AUTOC value since the reset operation sets back to deaults.
 	 */
 	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	if (hw->mac.link_settings_loaded) {
-		autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE);
-		autoc &= ~(IXGBE_AUTOC_LMS_MASK);
-		autoc |= hw->mac.link_attach_type;
-		autoc |= hw->mac.link_mode_select;
-		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
-	} else {
-		hw->mac.link_attach_type =
-		    (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
-		hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
-		hw->mac.link_settings_loaded = true;
+	if (hw->mac.orig_link_settings_stored == false) {
+		hw->mac.orig_autoc = autoc;
+		hw->mac.orig_link_settings_stored = true;
+	} else if (autoc != hw->mac.orig_autoc) {
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
 	}
 
+	/*
+	 * Store MAC address from RAR0, clear receive address registers, and
+	 * clear the multicast table
+	 */
+	hw->mac.ops.init_rx_addrs(hw);
+
 	/* Store the permanent mac address */
 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
 
@@ -895,63 +905,6 @@
 }
 
 /*
- * ixgbe_blink_led_start_82598 - Blink LED based on index.
- * @hw: pointer to hardware structure
- * @index: led number to blink
- */
-static s32
-ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index)
-{
-	ixgbe_link_speed speed = 0;
-	bool link_up = 0;
-	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
-	/*
-	 * Link must be up to auto-blink the LEDs on the 82598EB MAC;
-	 * force it if link is down.
-	 */
-	hw->mac.ops.check_link(hw, &speed, &link_up, false);
-
-	if (!link_up) {
-		autoc_reg |= IXGBE_AUTOC_FLU;
-		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-		msec_delay(10);
-	}
-
-	led_reg &= ~IXGBE_LED_MODE_MASK(index);
-	led_reg |= IXGBE_LED_BLINK(index);
-	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-	IXGBE_WRITE_FLUSH(hw);
-
-	return (IXGBE_SUCCESS);
-}
-
-/*
- * ixgbe_blink_led_stop_82598 - Stop blinking LED based on index.
- * @hw: pointer to hardware structure
- * @index: led number to stop blinking
- */
-static s32
-ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index)
-{
-	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
-	autoc_reg &= ~IXGBE_AUTOC_FLU;
-	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
-	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-
-	led_reg &= ~IXGBE_LED_MODE_MASK(index);
-	led_reg &= ~IXGBE_LED_BLINK(index);
-	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
-	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-	IXGBE_WRITE_FLUSH(hw);
-
-	return (IXGBE_SUCCESS);
-}
-
-/*
  * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
  * @hw: pointer to hardware structure
  * @reg: analog register to read
@@ -996,13 +949,12 @@
 }
 
 /*
- * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit EEPROM word of an SFP+ module
- * over I2C interface through an intermediate phy, such as NetLogic phy.
+ * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
  * @hw: pointer to hardware structure
  * @byte_offset: EEPROM byte offset to read
  * @eeprom_data: value read
  *
- * Performs byte read operation to SFP module's EEPROM over I2C interface.
+ * Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
  */
 s32
 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
@@ -1062,32 +1014,62 @@
  *
  * Determines physical layer capabilities of the current configuration.
  */
-s32
+u32
 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
 {
-	s32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+	u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+	u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+	u16 ext_ability = 0;
+
+	hw->phy.ops.identify(hw);
 
-	switch (hw->device_id) {
-	case IXGBE_DEV_ID_82598EB_CX4:
-	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
-		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
-		break;
-	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
-		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+	/*
+	 * Copper PHY must be checked before AUTOC LMS to determine correct
+	 * physical layer because 10GBase-T PHYs use LMS = KX4/KX
+	 */
+	if (hw->phy.type == ixgbe_phy_tn ||
+	    hw->phy.type == ixgbe_phy_cu_unknown) {
+		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
+		    IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
+		if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+		if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+		if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+		goto out;
+	}
+
+	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+	case IXGBE_AUTOC_LMS_1G_AN:
+	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+		if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
+			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+		else
+			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
 		break;
-	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
-	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
-	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
-		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+		if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+		else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+		else /* XAUI */
+			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
 		break;
-	case IXGBE_DEV_ID_82598EB_XF_LR:
-		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+	case IXGBE_AUTOC_LMS_KX4_AN:
+	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
+		if (autoc & IXGBE_AUTOC_KX_SUPP)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+		if (autoc & IXGBE_AUTOC_KX4_SUPP)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
 		break;
-	case IXGBE_DEV_ID_82598AT:
-		physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T |
-		    IXGBE_PHYSICAL_LAYER_1000BASE_T);
+	default:
 		break;
-	case IXGBE_DEV_ID_82598EB_SFP_LOM:
+	}
+
+	if (hw->phy.type == ixgbe_phy_nl) {
 		hw->phy.ops.identify_sfp(hw);
 
 		switch (hw->phy.sfp_type) {
@@ -1104,12 +1086,24 @@
 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
 			break;
 		}
-		break;
+	}
 
+	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
+		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+		break;
+	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
+		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+		break;
+	case IXGBE_DEV_ID_82598EB_XF_LR:
+		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+		break;
 	default:
-		physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
 		break;
 	}
 
+out:
 	return (physical_layer);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_82599.c	Sun Apr 12 18:46:02 2009 +0800
@@ -0,0 +1,2460 @@
+/*
+ * CDDL HEADER START
+ *
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at:
+ *      http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When using or redistributing this file, you may do so under the
+ * License only. No other modification of this header is permitted.
+ *
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* IntelVersion: 1.155 v2-7-8_2009-4-7 */
+
+#include "ixgbe_type.h"
+#include "ixgbe_api.h"
+#include "ixgbe_common.h"
+#include "ixgbe_phy.h"
+
+s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw);
+s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+    ixgbe_link_speed *speed, bool *autoneg);
+enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
+    ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete);
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw);
+s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw,
+    ixgbe_link_speed *speed,
+    bool *link_up, bool link_up_wait_to_complete);
+s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
+    ixgbe_link_speed speed, bool autoneg,
+    bool autoneg_wait_to_complete);
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw);
+static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
+    ixgbe_link_speed speed, bool autoneg,
+    bool autoneg_wait_to_complete);
+s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw);
+void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw);
+s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
+s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
+s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
+s32 ixgbe_insert_mac_addr_82599(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
+s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan,
+    u32 vind, bool vlan_on);
+s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw);
+s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw);
+s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
+s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
+s32 ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw);
+s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
+s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw);
+u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
+s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval);
+s32 ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw,
+    u16 *san_mac_offset);
+s32 ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr);
+s32 ixgbe_set_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr);
+s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps);
+
+void
+ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	DEBUGFUNC("ixgbe_init_mac_link_ops_82599");
+
+	if (hw->phy.multispeed_fiber) {
+		/* Set up dual speed SFP+ support */
+		mac->ops.setup_link =
+		    &ixgbe_setup_mac_link_multispeed_fiber;
+		mac->ops.setup_link_speed =
+		    &ixgbe_setup_mac_link_speed_multispeed_fiber;
+	} else {
+		mac->ops.setup_link =
+		    &ixgbe_setup_mac_link_82599;
+		mac->ops.setup_link_speed =
+		    &ixgbe_setup_mac_link_speed_82599;
+	}
+}
+
+/*
+ * ixgbe_init_phy_ops_82599 - PHY/SFP specific init
+ * @hw: pointer to hardware structure
+ *
+ * Initialize any function pointers that were not able to be
+ * set during init_shared_code because the PHY/SFP type was
+ * not known.  Perform the SFP init if necessary.
+ *
+ */
+s32
+ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mac_info *mac = &hw->mac;
+	struct ixgbe_phy_info *phy = &hw->phy;
+	s32 ret_val = IXGBE_SUCCESS;
+
+	DEBUGFUNC("ixgbe_init_phy_ops_82599");
+
+	/* Identify the PHY or SFP module */
+	ret_val = phy->ops.identify(hw);
+
+	/* Setup function pointers based on detected SFP module and speeds */
+	ixgbe_init_mac_link_ops_82599(hw);
+	if (hw->phy.sfp_type != ixgbe_sfp_type_unknown)
+		hw->phy.ops.reset = NULL;
+
+	/* If copper media, overwrite with copper function pointers */
+	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+		mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
+		mac->ops.setup_link_speed =
+		    &ixgbe_setup_copper_link_speed_82599;
+		mac->ops.get_link_capabilities =
+		    &ixgbe_get_copper_link_capabilities_generic;
+	}
+
+	/* Set necessary function pointers based on phy type */
+	switch (hw->phy.type) {
+	case ixgbe_phy_tn:
+		phy->ops.check_link = &ixgbe_check_phy_link_tnx;
+		phy->ops.get_firmware_version =
+		    &ixgbe_get_phy_firmware_version_tnx;
+		break;
+	default:
+		break;
+	}
+
+	return (ret_val);
+}
+
+s32
+ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
+{
+	s32 ret_val = IXGBE_SUCCESS;
+	u16 list_offset, data_offset, data_value;
+
+	DEBUGFUNC("ixgbe_setup_sfp_modules_82599");
+
+	if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
+		ixgbe_init_mac_link_ops_82599(hw);
+
+		hw->phy.ops.reset = NULL;
+
+		ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
+		    &data_offset);
+
+		if (ret_val != IXGBE_SUCCESS)
+			goto setup_sfp_out;
+
+		hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+		while (data_value != 0xffff) {
+			IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
+			IXGBE_WRITE_FLUSH(hw);
+			hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+		}
+		/* Now restart DSP */
+		IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000102);
+		IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000b1d);
+		IXGBE_WRITE_FLUSH(hw);
+	}
+
+setup_sfp_out:
+	return (ret_val);
+}
+
+/*
+ * ixgbe_get_pcie_msix_count_82599 - Gets MSI-X vector count
+ * @hw: pointer to hardware structure
+ *
+ * Read PCIe configuration space, and get the MSI-X vector count from
+ * the capabilities table.
+ */
+u32
+ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
+{
+	u32 msix_count = 64;
+
+	if (hw->mac.msix_vectors_from_pcie) {
+		msix_count = IXGBE_READ_PCIE_WORD(hw,
+		    IXGBE_PCIE_MSIX_82599_CAPS);
+		msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+
+		/*
+		 * MSI-X count is zero-based in HW, so increment to give
+		 * proper value
+		 */
+		msix_count++;
+	}
+
+	return (msix_count);
+}
+
+/*
+ * ixgbe_init_ops_82599 - Inits func ptrs and MAC type
+ * @hw: pointer to hardware structure
+ *
+ * Initialize the function pointers and assign the MAC type for 82599.
+ * Does not touch the hardware.
+ */
+
+s32
+ixgbe_init_ops_82599(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mac_info *mac = &hw->mac;
+	struct ixgbe_phy_info *phy = &hw->phy;
+	s32 ret_val;
+
+	ret_val = ixgbe_init_phy_ops_generic(hw);
+	ret_val = ixgbe_init_ops_generic(hw);
+
+	/* PHY */
+	phy->ops.identify = &ixgbe_identify_phy_82599;
+	phy->ops.init = &ixgbe_init_phy_ops_82599;
+
+	/* MAC */
+	mac->ops.reset_hw = &ixgbe_reset_hw_82599;
+	mac->ops.get_media_type = &ixgbe_get_media_type_82599;
+	mac->ops.get_supported_physical_layer =
+	    &ixgbe_get_supported_physical_layer_82599;
+	mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_82599;
+	mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82599;
+	mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82599;
+	mac->ops.start_hw = &ixgbe_start_hw_rev_1_82599;
+	mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_82599;
+	mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_82599;
+	mac->ops.get_device_caps = &ixgbe_get_device_caps_82599;
+
+	/* RAR, Multicast, VLAN */
+	mac->ops.set_vmdq = &ixgbe_set_vmdq_82599;
+	mac->ops.clear_vmdq = &ixgbe_clear_vmdq_82599;
+	mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_82599;
+	mac->rar_highwater = 1;
+	mac->ops.set_vfta = &ixgbe_set_vfta_82599;
+	mac->ops.clear_vfta = &ixgbe_clear_vfta_82599;
+	mac->ops.init_uta_tables = &ixgbe_init_uta_tables_82599;
+	mac->ops.setup_sfp = &ixgbe_setup_sfp_modules_82599;
+
+	/* Link */
+	mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82599;
+	mac->ops.check_link = &ixgbe_check_mac_link_82599;
+	ixgbe_init_mac_link_ops_82599(hw);
+
+	mac->mcft_size = 128;
+	mac->vft_size = 128;
+	mac->num_rar_entries = 128;
+	mac->max_tx_queues = 128;
+	mac->max_rx_queues = 128;
+	mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
+
+	return (ret_val);
+}
+
+/*
+ * ixgbe_get_link_capabilities_82599 - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @negotiation: true when autoneg or autotry is enabled
+ *
+ * Determines the link capabilities by reading the AUTOC register.
+ */
+s32
+ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+    ixgbe_link_speed *speed, bool *negotiation)
+{
+	s32 status = IXGBE_SUCCESS;
+	u32 autoc = 0;
+
+	/*
+	 * Determine link capabilities based on the stored value of AUTOC,
+	 * which represents EEPROM defaults.  If AUTOC value has not
+	 * been stored, use the current register values.
+	 */
+	if (hw->mac.orig_link_settings_stored)
+		autoc = hw->mac.orig_autoc;
+	else
+		autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+		*speed = IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = false;
+		break;
+
+	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+		*speed = IXGBE_LINK_SPEED_10GB_FULL;
+		*negotiation = false;
+		break;
+
+	case IXGBE_AUTOC_LMS_1G_AN:
+		*speed = IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = true;
+		break;
+
+	case IXGBE_AUTOC_LMS_10G_SERIAL:
+		*speed = IXGBE_LINK_SPEED_10GB_FULL;
+		*negotiation = false;
+		break;
+
+	case IXGBE_AUTOC_LMS_KX4_KX_KR:
+	case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
+		*speed = IXGBE_LINK_SPEED_UNKNOWN;
+		if (autoc & IXGBE_AUTOC_KR_SUPP)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (autoc & IXGBE_AUTOC_KX4_SUPP)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (autoc & IXGBE_AUTOC_KX_SUPP)
+			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = true;
+		break;
+
+	case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
+		*speed = IXGBE_LINK_SPEED_100_FULL;
+		if (autoc & IXGBE_AUTOC_KR_SUPP)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (autoc & IXGBE_AUTOC_KX4_SUPP)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (autoc & IXGBE_AUTOC_KX_SUPP)
+			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = true;
+		break;
+
+	case IXGBE_AUTOC_LMS_SGMII_1G_100M:
+		*speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
+		*negotiation = false;
+		break;
+
+	default:
+		status = IXGBE_ERR_LINK_SETUP;
+		goto out;
+	}
+
+	if (hw->phy.multispeed_fiber) {
+		*speed |= IXGBE_LINK_SPEED_10GB_FULL |
+		    IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = true;
+	}
+
+out:
+	return (status);
+}
+
+/*
+ * ixgbe_get_media_type_82599 - Get media type
+ * @hw: pointer to hardware structure
+ *
+ * Returns the media type (fiber, copper, backplane)
+ */
+enum ixgbe_media_type
+ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
+{
+	enum ixgbe_media_type media_type;
+
+	/* Detect if there is a copper PHY attached. */
+	if (hw->phy.type == ixgbe_phy_cu_unknown ||
+	    hw->phy.type == ixgbe_phy_tn) {
+		media_type = ixgbe_media_type_copper;
+		goto out;
+	}
+
+	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82599_KX4:
+	case IXGBE_DEV_ID_82599_KX4_SIK:
+		/* Default device ID is mezzanine card KX/KX4 */
+		media_type = ixgbe_media_type_backplane;
+		break;
+	case IXGBE_DEV_ID_82599_SFP:
+	case IXGBE_DEV_ID_82599_SPW:
+		media_type = ixgbe_media_type_fiber;
+		break;
+	case IXGBE_DEV_ID_82599_CX4:
+		media_type = ixgbe_media_type_fiber;
+		break;
+	default:
+		media_type = ixgbe_media_type_unknown;
+		break;
+	}
+out:
+	return (media_type);
+}
+
+/*
+ * ixgbe_setup_mac_link_82599 - Setup MAC link settings
+ * @hw: pointer to hardware structure
+ *
+ * Configures link settings based on values in the ixgbe_hw struct.
+ * Restarts the link.  Performs autonegotiation if needed.
+ */
+s32
+ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
+{
+	u32 autoc_reg;
+	u32 links_reg;
+	u32 i;
+	s32 status = IXGBE_SUCCESS;
+
+	/* Restart link */
+	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+	/* Only poll for autoneg to complete if specified to do so */
+	if (hw->phy.autoneg_wait_to_complete) {
+		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		    IXGBE_AUTOC_LMS_KX4_KX_KR ||
+		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		    IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		    IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+			links_reg = 0; /* Just in case Autoneg time = 0 */
+			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
+				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+				if (links_reg & IXGBE_LINKS_KX_AN_COMP)
+					break;
+				msec_delay(100);
+			}
+			if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
+				status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
+				DEBUGOUT("Autoneg did not complete.\n");
+			}
+		}
+	}
+
+	/* Add delay to filter out noises during initial link setup */
+	msec_delay(50);
+
+	return (status);
+}
+
+/*
+ * ixgbe_setup_mac_link_multispeed_fiber - Setup MAC link settings
+ * @hw: pointer to hardware structure
+ *
+ * Configures link settings based on values in the ixgbe_hw struct.
+ * Restarts the link for multi-speed fiber at 1G speed, if link
+ * fails at 10G.
+ * Performs autonegotiation if needed.
+ */
+s32
+ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw)
+{
+	s32 status = IXGBE_SUCCESS;
+	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_82599_AUTONEG;
+	DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber");
+
+	status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw,
+	    link_speed, true, true);
+	return (status);
+}
+
+/*
+ * ixgbe_setup_mac_link_speed_multispeed_fiber - Set MAC link speed
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ * Set the link speed in the AUTOC register and restarts link.
+ */
+s32
+ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
+    ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete)
+{
+	s32 status = IXGBE_SUCCESS;
+	ixgbe_link_speed link_speed;
+	ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
+	u32 speedcnt = 0;
+	u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+	bool link_up = false;
+	bool negotiation;
+
+	/* Mask off requested but non-supported speeds */
+	status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
+	if (status != IXGBE_SUCCESS)
+		goto out;
+
+	speed &= link_speed;
+
+	/*
+	 * Try each speed one by one, highest priority first.  We do this in
+	 * software because 10gb fiber doesn't support speed autonegotiation.
+	 */
+	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
+		speedcnt++;
+		highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+
+		/* If we already have link at this speed, just jump out */
+		status = ixgbe_check_link(hw, &link_speed, &link_up, false);
+		if (status != IXGBE_SUCCESS)
+			goto out;
+
+		if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
+			goto out;
+
+		/* Set hardware SDP's */
+		esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+
+		/* Allow module to change analog characteristics (1G->10G) */
+		msec_delay(40);
+
+		status = ixgbe_setup_mac_link_speed_82599(
+		    hw, IXGBE_LINK_SPEED_10GB_FULL, autoneg,
+		    autoneg_wait_to_complete);
+		if (status != IXGBE_SUCCESS)
+			goto out;
+
+		msec_delay(100);
+
+		/* If we have link, just jump out */
+		status = ixgbe_check_link(hw, &link_speed, &link_up, false);
+		if (status != IXGBE_SUCCESS)
+			goto out;
+
+		if (link_up)
+			goto out;
+	}
+
+	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
+		speedcnt++;
+		if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
+			highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
+
+		/* If we already have link at this speed, just jump out */
+		status = ixgbe_check_link(hw, &link_speed, &link_up, false);
+		if (status != IXGBE_SUCCESS)
+			goto out;
+
+		if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
+			goto out;
+
+		/* Set hardware SDP's */
+		esdp_reg &= ~IXGBE_ESDP_SDP5;
+		esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+
+		/* Allow module to change analog characteristics (10G->1G) */
+		msec_delay(40);
+
+		status = ixgbe_setup_mac_link_speed_82599(
+		    hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg,
+		    autoneg_wait_to_complete);
+		if (status != IXGBE_SUCCESS)
+			goto out;
+
+		msec_delay(100);
+
+		/* If we have link, just jump out */
+		status = ixgbe_check_link(hw, &link_speed, &link_up, false);
+		if (status != IXGBE_SUCCESS)
+			goto out;
+
+		if (link_up)
+			goto out;
+	}
+
+	/*
+	 * We didn't get link.  Configure back to the highest speed we tried,
+	 * (if there was more than one).  We call ourselves back with just the
+	 * single highest speed that the user requested.
+	 */
+	if (speedcnt > 1)
+		status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw,
+		    highest_link_speed, autoneg, autoneg_wait_to_complete);
+
+out:
+	return (status);
+}
+
+/*
+ * ixgbe_check_mac_link_82599 - Determine link and speed status
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @link_up: true when link is up
+ * @link_up_wait_to_complete: bool used to wait for link up or not
+ *
+ * Reads the links register to determine if link is up and the current speed
+ */
+s32
+ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
+    bool *link_up, bool link_up_wait_to_complete)
+{
+	u32 links_reg;
+	u32 i;
+
+	links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+	if (link_up_wait_to_complete) {
+		for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
+			if (links_reg & IXGBE_LINKS_UP) {
+				*link_up = true;
+				break;
+			} else {
+				*link_up = false;
+			}
+			msec_delay(100);
+			links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+		}
+	} else {
+		if (links_reg & IXGBE_LINKS_UP)
+			*link_up = true;
+		else
+			*link_up = false;
+	}
+
+	if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
+	    IXGBE_LINKS_SPEED_10G_82599)
+		*speed = IXGBE_LINK_SPEED_10GB_FULL;
+	else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
+	    IXGBE_LINKS_SPEED_1G_82599)
+		*speed = IXGBE_LINK_SPEED_1GB_FULL;
+	else
+		*speed = IXGBE_LINK_SPEED_100_FULL;
+
+	/* if link is down, zero out the current_mode */
+	if (*link_up == false) {
+		hw->fc.current_mode = ixgbe_fc_none;
+		hw->fc.fc_was_autonegged = false;
+	}
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_setup_mac_link_speed_82599 - Set MAC link speed
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ * Set the link speed in the AUTOC register and restarts link.
+ */
+s32
+ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
+    ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete)
+{
+	s32 status = IXGBE_SUCCESS;
+	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+	u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
+	u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+	u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
+	u32 links_reg;
+	u32 i;
+	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+
+	/* Check to see if speed passed in is supported. */
+	status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
+	if (status != IXGBE_SUCCESS)
+		goto out;
+
+	speed &= link_capabilities;
+
+	if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
+		status = IXGBE_ERR_LINK_SETUP;
+	} else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+	    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+	    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+		/* Set KX4/KX/KR support according to speed requested */
+		autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
+		if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+			if (autoc & IXGBE_AUTOC_KX4_SUPP)
+				autoc |= IXGBE_AUTOC_KX4_SUPP;
+			if (autoc & IXGBE_AUTOC_KR_SUPP)
+				autoc |= IXGBE_AUTOC_KR_SUPP;
+		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+			autoc |= IXGBE_AUTOC_KX_SUPP;
+	} else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) &&
+	    (link_mode == IXGBE_AUTOC_LMS_1G_LINK_NO_AN ||
+	    link_mode == IXGBE_AUTOC_LMS_1G_AN)) {
+		/* Switch from 1G SFI to 10G SFI if requested */
+		if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
+		    (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)) {
+			autoc &= ~IXGBE_AUTOC_LMS_MASK;
+			autoc |= IXGBE_AUTOC_LMS_10G_SERIAL;
+		}
+	} else if ((pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) &&
+	    (link_mode == IXGBE_AUTOC_LMS_10G_SERIAL)) {
+		/* Switch from 10G SFI to 1G SFI if requested */
+		if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
+		    (pma_pmd_1g == IXGBE_AUTOC_1G_SFI)) {
+			autoc &= ~IXGBE_AUTOC_LMS_MASK;
+			if (autoneg)
+				autoc |= IXGBE_AUTOC_LMS_1G_AN;
+			else
+				autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
+			}
+	}
+
+	if (status == IXGBE_SUCCESS) {
+		/* Restart link */
+		autoc |= IXGBE_AUTOC_AN_RESTART;
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+
+		/* Only poll for autoneg to complete if specified to do so */
+		if (autoneg_wait_to_complete) {
+			if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+			    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+			    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+				links_reg = 0; /* Just in case Autoneg time=0 */
+				for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
+					links_reg =
+					    IXGBE_READ_REG(hw, IXGBE_LINKS);
+					if (links_reg & IXGBE_LINKS_KX_AN_COMP)
+						break;
+					msec_delay(100);
+				}
+				if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
+					status =
+					    IXGBE_ERR_AUTONEG_NOT_COMPLETE;
+					DEBUGOUT("Autoneg did not complete.\n");
+				}
+			}
+		}
+
+		/* Add delay to filter out noises during initial link setup */
+		msec_delay(50);
+	}
+
+out:
+	return (status);
+}
+
+/*
+ * ixgbe_setup_copper_link_82599 - Setup copper link settings
+ * @hw: pointer to hardware structure
+ *
+ * Restarts the link on PHY and then MAC. Performs autonegotiation if needed.
+ */
+static s32
+ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw)
+{
+	s32 status;
+
+	/* Restart autonegotiation on PHY */
+	status = hw->phy.ops.setup_link(hw);
+
+	/* Set up MAC */
+	(void) ixgbe_setup_mac_link_82599(hw);
+
+	return (status);
+}
+
+/*
+ * ixgbe_setup_copper_link_speed_82599 - Set the PHY autoneg advertised field
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true if waiting is needed to complete
+ *
+ * Restarts link on PHY and MAC based on settings passed in.
+ */
+static s32
+ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
+    ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete)
+{
+	s32 status;
+
+	/* Setup the PHY according to input speed */
+	status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+	    autoneg_wait_to_complete);
+	/* Set up MAC */
+	(void) ixgbe_setup_mac_link_82599(hw);
+
+	return (status);
+}
+/*
+ * ixgbe_reset_hw_82599 - Perform hardware reset
+ * @hw: pointer to hardware structure
+ *
+ * Resets the hardware by resetting the transmit and receive units, masks
+ * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
+ * reset.
+ */
+s32
+ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
+{
+	s32 status = IXGBE_SUCCESS;
+	u32 ctrl, ctrl_ext;
+	u32 i;
+	u32 autoc;
+	u32 autoc2;
+
+	/* Call adapter stop to disable tx/rx and clear interrupts */
+	hw->mac.ops.stop_adapter(hw);
+
+	/* PHY ops must be identified and initialized prior to reset */
+
+	/* Identify PHY and related function pointers */
+	status = hw->phy.ops.init(hw);
+
+	/* Setup SFP module if there is one present. */
+	if (hw->phy.sfp_setup_needed) {
+		status = hw->mac.ops.setup_sfp(hw);
+		hw->phy.sfp_setup_needed = false;
+	}
+
+	/* Reset PHY */
+	if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
+		hw->phy.ops.reset(hw);
+
+	/*
+	 * Prevent the PCI-E bus from from hanging by disabling PCI-E master
+	 * access and verify no pending requests before reset
+	 */
+	status = ixgbe_disable_pcie_master(hw);
+	if (status != IXGBE_SUCCESS) {
+		status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
+		DEBUGOUT("PCI-E Master disable polling has failed.\n");
+	}
+
+	/*
+	 * Issue global reset to the MAC.  This needs to be a SW reset.
+	 * If link reset is used, it might reset the MAC when mng is using it
+	 */
+	ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+	IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
+	IXGBE_WRITE_FLUSH(hw);
+
+	/* Poll for reset bit to self-clear indicating reset is complete */
+	for (i = 0; i < 10; i++) {
+		usec_delay(1);
+		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+		if (!(ctrl & IXGBE_CTRL_RST)) {
+			break;
+		}
+	}
+	if (ctrl & IXGBE_CTRL_RST) {
+		status = IXGBE_ERR_RESET_FAILED;
+		DEBUGOUT("Reset polling failed to complete.\n");
+	}
+
+	/* Clear PF Reset Done bit so PF/VF Mail Ops can work */
+	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
+	ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
+	IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+
+	msec_delay(50);
+
+	/*
+	 * Store the original AUTOC/AUTOC2 values if they have not been
+	 * stored off yet.  Otherwise restore the stored original
+	 * values since the reset operation sets back to defaults.
+	 */
+	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+	if (hw->mac.orig_link_settings_stored == false) {
+		hw->mac.orig_autoc = autoc;
+		hw->mac.orig_autoc2 = autoc2;
+		hw->mac.orig_link_settings_stored = true;
+	} else {
+		if (autoc != hw->mac.orig_autoc) {
+			IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
+			    IXGBE_AUTOC_AN_RESTART));
+		}
+
+		if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
+		    (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
+			autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
+			autoc2 |= (hw->mac.orig_autoc2 &
+			    IXGBE_AUTOC2_UPPER_MASK);
+			IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
+		}
+	}
+
+	/*
+	 * Store MAC address from RAR0, clear receive address registers, and
+	 * clear the multicast table.  Also reset num_rar_entries to 128,
+	 * since we modify this value when programming the SAN MAC address.
+	 */
+	hw->mac.num_rar_entries = 128;
+	hw->mac.ops.init_rx_addrs(hw);
+
+	/* Store the permanent mac address */
+	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+
+	/* Add the SAN MAC address to the RAR only if it's a valid address */
+	if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
+		hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
+		    hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+		/* Reserve the last RAR for the SAN MAC address */
+		hw->mac.num_rar_entries--;
+	}
+
+	return (status);
+}
+
+/*
+ * ixgbe_insert_mac_addr_82599 - Find a RAR for this mac address
+ * @hw: pointer to hardware structure
+ * @addr: Address to put into receive address register
+ * @vmdq: VMDq pool to assign
+ *
+ * Puts an ethernet address into a receive address register, or
+ * finds the rar that it is aleady in; adds to the pool list
+ */
+s32
+ixgbe_insert_mac_addr_82599(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
+{
+	static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF;
+	u32 first_empty_rar = NO_EMPTY_RAR_FOUND;
+	u32 rar;
+	u32 rar_low, rar_high;
+	u32 addr_low, addr_high;
+
+	/* swap bytes for HW little endian */
+	addr_low  = addr[0] | (addr[1] << 8)
+	    | (addr[2] << 16)
+	    | (addr[3] << 24);
+	addr_high = addr[4] | (addr[5] << 8);
+
+	/*
+	 * Either find the mac_id in rar or find the first empty space.
+	 * rar_highwater points to just after the highest currently used
+	 * rar in order to shorten the search.  It grows when we add a new
+	 * rar to the top.
+	 */
+	for (rar = 0; rar < hw->mac.rar_highwater; rar++) {
+		rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
+
+		if (((IXGBE_RAH_AV & rar_high) == 0) &&
+		    first_empty_rar == NO_EMPTY_RAR_FOUND) {
+			first_empty_rar = rar;
+		} else if ((rar_high & 0xFFFF) == addr_high) {
+			rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar));
+			if (rar_low == addr_low)
+				break;	  /* found it already in the rars */
+		}
+	}
+
+	if (rar < hw->mac.rar_highwater) {
+		/* already there so just add to the pool bits */
+		(void) ixgbe_set_vmdq(hw, rar, vmdq);
+	} else if (first_empty_rar != NO_EMPTY_RAR_FOUND) {
+		/* stick it into first empty RAR slot we found */
+		rar = first_empty_rar;
+		(void) ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
+	} else if (rar == hw->mac.rar_highwater) {
+		/* add it to the top of the list and inc the highwater mark */
+		(void) ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
+		hw->mac.rar_highwater++;
+	} else if (rar >= hw->mac.num_rar_entries) {
+		return (IXGBE_ERR_INVALID_MAC_ADDR);
+	}
+
+	/*
+	 * If we found rar[0], make sure the default pool bit (we use pool 0)
+	 * remains cleared to be sure default pool packets will get delivered
+	 */
+	if (rar == 0)
+		(void) ixgbe_clear_vmdq(hw, rar, 0);
+
+	return (rar);
+}
+
+/*
+ * ixgbe_clear_vmdq_82599 - Disassociate a VMDq pool index from a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to disassociate
+ * @vmdq: VMDq pool index to remove from the rar
+ */
+s32
+ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+	u32 mpsar_lo, mpsar_hi;
+	u32 rar_entries = hw->mac.num_rar_entries;
+
+	if (rar < rar_entries) {
+		mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
+		mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
+
+		if (!mpsar_lo && !mpsar_hi) {
+			goto done;
+		}
+
+		if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
+			if (mpsar_lo) {
+				IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
+				mpsar_lo = 0;
+			}
+			if (mpsar_hi) {
+				IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
+				mpsar_hi = 0;
+			}
+		} else if (vmdq < 32) {
+			mpsar_lo &= ~(1 << vmdq);
+			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
+		} else {
+			mpsar_hi &= ~(1 << (vmdq - 32));
+			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
+		}
+
+		/* was that the last pool using this rar? */
+		if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) {
+			hw->mac.ops.clear_rar(hw, rar);
+		}
+	} else {
+		DEBUGOUT1("RAR index %d is out of range.\n", rar);
+	}
+done:
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_set_vmdq_82599 - Associate a VMDq pool index with a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to associate with a VMDq index
+ * @vmdq: VMDq pool index
+ */
+s32
+ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+	u32 mpsar;
+	u32 rar_entries = hw->mac.num_rar_entries;
+
+	if (rar < rar_entries) {
+		if (vmdq < 32) {
+			mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
+			mpsar |= 1 << vmdq;
+			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
+		} else {
+			mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
+			mpsar |= 1 << (vmdq - 32);
+			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
+		}
+	} else {
+		DEBUGOUT1("RAR index %d is out of range.\n", rar);
+	}
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_set_vfta_82599 - Set VLAN filter table
+ * @hw: pointer to hardware structure
+ * @vlan: VLAN id to write to VLAN filter
+ * @vind: VMDq output index that maps queue to VLAN id in VFVFB
+ * @vlan_on: boolean flag to turn on/off VLAN in VFVF
+ *
+ * Turn on/off specified VLAN in the VLAN filter table.
+ */
+s32
+ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on)
+{
+	u32 regindex;
+	u32 bitindex;
+	u32 bits;
+	u32 first_empty_slot;
+
+	if (vlan > 4095) {
+		return (IXGBE_ERR_PARAM);
+	}
+
+	/*
+	 * this is a 2 part operation - first the VFTA, then the
+	 * VLVF and VLVFB if vind is set
+	 */
+
+	/*
+	 * Part 1
+	 * The VFTA is a bitstring made up of 128 32-bit registers
+	 * that enable the particular VLAN id, much like the MTA:
+	 *    bits[11-5]: which register
+	 *    bits[4-0]:  which bit in the register
+	 */
+	regindex = (vlan >> 5) & 0x7F;
+	bitindex = vlan & 0x1F;
+	bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+	if (vlan_on) {
+		bits |= (1 << bitindex);
+	} else {
+		bits &= ~(1 << bitindex);
+	}
+	IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
+
+
+	/*
+	 * Part 2
+	 * If the vind is set
+	 *   Either vlan_on
+	 *	make sure the vlan is in VLVF
+	 *	set the vind bit in the matching VLVFB
+	 *   Or !vlan_on
+	 *	clear the pool bit and possibly the vind
+	 */
+	if (vind) {
+		/* find the vlanid or the first empty slot */
+		first_empty_slot = 0;
+
+		for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+			bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
+			if (!bits && !first_empty_slot)
+				first_empty_slot = regindex;
+			else if ((bits & 0x0FFF) == vlan)
+				break;
+		}
+
+		if (regindex >= IXGBE_VLVF_ENTRIES) {
+			if (first_empty_slot)
+				regindex = first_empty_slot;
+			else {
+				DEBUGOUT("No space in VLVF.\n");
+			}
+		}
+
+
+		if (vlan_on) {
+			/* set the pool bit */
+			if (vind < 32) {
+				bits =
+				    IXGBE_READ_REG(hw, IXGBE_VLVFB(regindex*2));
+				bits |= (1 << vind);
+				IXGBE_WRITE_REG(hw,
+				    IXGBE_VLVFB(regindex*2), bits);
+			} else {
+				bits = IXGBE_READ_REG(hw,
+				    IXGBE_VLVFB((regindex*2)+1));
+				bits |= (1 << vind);
+				IXGBE_WRITE_REG(hw,
+				    IXGBE_VLVFB((regindex*2)+1), bits);
+			}
+		} else {
+			/* clear the pool bit */
+			if (vind < 32) {
+				bits = IXGBE_READ_REG(hw,
+				    IXGBE_VLVFB(regindex*2));
+			bits &= ~(1 << vind);
+				IXGBE_WRITE_REG(hw,
+				    IXGBE_VLVFB(regindex*2), bits);
+				bits |= IXGBE_READ_REG(hw,
+				    IXGBE_VLVFB((regindex*2)+1));
+			} else {
+				bits = IXGBE_READ_REG(hw,
+				    IXGBE_VLVFB((regindex*2)+1));
+				bits &= ~(1 << vind);
+				IXGBE_WRITE_REG(hw,
+				    IXGBE_VLVFB((regindex*2)+1), bits);
+				bits |= IXGBE_READ_REG(hw,
+				    IXGBE_VLVFB(regindex*2));
+			}
+		}
+
+		if (bits)
+			IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex),
+			    (IXGBE_VLVF_VIEN | vlan));
+		else
+			IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0);
+	}
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_clear_vfta_82599 - Clear VLAN filter table
+ * @hw: pointer to hardware structure
+ *
+ * Clears the VLAN filer table, and the VMDq index associated with the filter
+ */
+s32
+ixgbe_clear_vfta_82599(struct ixgbe_hw *hw)
+{
+	u32 offset;
+
+	for (offset = 0; offset < hw->mac.vft_size; offset++)
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+
+	for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0);
+	}
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array
+ * @hw: pointer to hardware structure
+ */
+s32
+ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw)
+{
+	int i;
+	DEBUGOUT(" Clearing UTA\n");
+
+	for (i = 0; i < 128; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
+ * @hw: pointer to hardware structure
+ */
+s32
+ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
+{
+	u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
+	fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
+	IXGBE_WRITE_FLUSH(hw);
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
+
+	return (IXGBE_SUCCESS);
+}
+
+#define	IXGBE_FDIR_INIT_DONE_POLL	10
+/*
+ * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters
+ * @hw: pointer to hardware structure
+ * @pballoc: which mode to allocate filters with
+ */
+s32
+ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc)
+{
+	u32 fdirctrl = 0;
+	u32 pbsize;
+	int i;
+
+	/*
+	 * Before enabling Flow Director, the Rx Packet Buffer size
+	 * must be reduced.  The new value is the current size minus
+	 * flow director memory usage size.
+	 */
+	pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc));
+	IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
+	    IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize);
+
+	/*
+	 * The defaults in the HW for RX PB 1-7 are not zero and so should be
+	 * intialized to zero for non DCB mode otherwise actual total RX PB
+	 * would be bigger than programmed and filter space would run into
+	 * the PB 0 region.
+	 */
+	for (i = 1; i < 8; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
+
+	/* Send interrupt when 64 filters are left */
+	fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
+
+	/* Set the maximum length per hash bucket to 0xA filters */
+	fdirctrl |= 0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT;
+
+	switch (pballoc) {
+	case IXGBE_FDIR_PBALLOC_64K:
+		/* 8k - 1 signature filters */
+		fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
+		break;
+	case IXGBE_FDIR_PBALLOC_128K:
+		/* 16k - 1 signature filters */
+		fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
+		break;
+	case IXGBE_FDIR_PBALLOC_256K:
+		/* 32k - 1 signature filters */
+		fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
+		break;
+	default:
+		/* bad value */
+		return (IXGBE_ERR_CONFIG);
+	};
+
+	/* Move the flexible bytes to use the ethertype - shift 6 words */
+	fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
+
+	/* Prime the keys for hashing */
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY,
+	    IXGBE_HTONL(IXGBE_ATR_BUCKET_HASH_KEY));
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY,
+	    IXGBE_HTONL(IXGBE_ATR_SIGNATURE_HASH_KEY));
+
+	/*
+	 * Poll init-done after we write the register.  Estimated times:
+	 *   10G: PBALLOC = 11b, timing is 60us
+	 *    1G: PBALLOC = 11b, timing is 600us
+	 *  100M: PBALLOC = 11b, timing is 6ms
+	 *
+	 *   Multiple these timings by 4 if under full Rx load
+	 *
+	 * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
+	 * 1 msec per poll time.  If we're at line rate and drop to 100M, then
+	 * this might not finish in our poll time, but we can live with that
+	 * for now.
+	 */
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
+	IXGBE_WRITE_FLUSH(hw);
+	for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
+		if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
+		    IXGBE_FDIRCTRL_INIT_DONE)
+			break;
+
+		msec_delay(1);
+	}
+	if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
+		DEBUGOUT("Flow Director Signature poll time exceeded!\n");
+	}
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters
+ * @hw: pointer to hardware structure
+ * @pballoc: which mode to allocate filters with
+ */
+s32
+ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
+{
+	u32 fdirctrl = 0;
+	u32 pbsize;
+	int i;
+
+	/*
+	 * Before enabling Flow Director, the Rx Packet Buffer size
+	 * must be reduced.  The new value is the current size minus
+	 * flow director memory usage size.
+	 */
+
+	pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc));
+	IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
+	    IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize);
+
+	/*
+	 * The defaults in the HW for RX PB 1-7 are not zero and so should be
+	 * intialized to zero for non DCB mode otherwise actual total RX PB
+	 * would be bigger than programmed and filter space would run into
+	 * the PB 0 region.
+	 */
+	for (i = 1; i < 8; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
+
+	/* Send interrupt when 64 filters are left */
+	fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
+
+	switch (pballoc) {
+	case IXGBE_FDIR_PBALLOC_64K:
+		/* 2k - 1 perfect filters */
+		fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
+		break;
+	case IXGBE_FDIR_PBALLOC_128K:
+		/* 4k - 1 perfect filters */
+		fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
+		break;
+	case IXGBE_FDIR_PBALLOC_256K:
+		/* 8k - 1 perfect filters */
+		fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
+		break;
+	default:
+		/* bad value */
+		return (IXGBE_ERR_CONFIG);
+	};
+
+	/* Turn perfect match filtering on */
+	fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH;
+	fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS;
+
+	/* Move the flexible bytes to use the ethertype - shift 6 words */
+	fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
+
+	/* Prime the keys for hashing */
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY,
+	    IXGBE_HTONL(IXGBE_ATR_BUCKET_HASH_KEY));
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY,
+	    IXGBE_HTONL(IXGBE_ATR_SIGNATURE_HASH_KEY));
+
+	/*
+	 * Poll init-done after we write the register.  Estimated times:
+	 *   10G: PBALLOC = 11b, timing is 60us
+	 *    1G: PBALLOC = 11b, timing is 600us
+	 *  100M: PBALLOC = 11b, timing is 6ms
+	 *
+	 *  Multiple these timings by 4 if under full Rx load
+	 *
+	 * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
+	 * 1 msec per poll time.  If we're at line rate and drop to 100M, then
+	 * this might not finish in our poll time, but we can live with that
+	 * for now.
+	 */
+
+	/* Set the maximum length per hash bucket to 0xA filters */
+	fdirctrl |= (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT);
+
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
+	IXGBE_WRITE_FLUSH(hw);
+	for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
+		if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
+		    IXGBE_FDIRCTRL_INIT_DONE)
+			break;
+
+		msec_delay(1);
+	}
+	if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
+		DEBUGOUT("Flow Director Perfect poll time exceeded!\n");
+	}
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_compute_hash_82599 - Compute the hashes for SW ATR
+ * @stream: input bitstream to compute the hash on
+ * @key: 32-bit hash key
+ */
+u16
+ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, u32 key)
+{
+	/*
+	 * The algorithm is as follows:
+	 *    Hash[15:0] = Sum { S[n] x K[n+16] }, n = 0...350
+	 *    where Sum {A[n]}, n = 0...n is bitwise XOR of A[0], A[1]...A[n]
+	 *    and A[n] x B[n] is bitwise AND between same length strings
+	 *
+	 *    K[n] is 16 bits, defined as:
+	 *	for n modulo 32 >= 15, K[n] = K[n % 32 : (n % 32) - 15]
+	 *	for n modulo 32 < 15, K[n] =
+	 *		K[(n % 32:0) | (31:31 - (14 - (n % 32)))]
+	 *
+	 *    S[n] is 16 bits, defined as:
+	 *	for n >= 15, S[n] = S[n:n - 15]
+	 *	for n < 15, S[n] = S[(n:0) | (350:350 - (14 - n))]
+	 *
+	 *    To simplify for programming, the algorithm is implemented
+	 *    in software this way:
+	 *
+	 *    Key[31:0], Stream[335:0]
+	 *
+	 *    tmp_key[11 * 32 - 1:0] = 11{Key[31:0] = key concatenated 11 times
+	 *    int_key[350:0] = tmp_key[351:1]
+	 *    int_stream[365:0] = Stream[14:0] | Stream[335:0] | Stream[335:321]
+	 *
+	 *    hash[15:0] = 0;
+	 *    for (i = 0; i < 351; i++) {
+	 *	if (int_key[i])
+	 *	hash ^= int_stream[(i + 15):i];
+	 *    }
+	 */
+
+	union {
+		u32	key[11];
+		u8	key_stream[44];
+	} tmp_key;
+
+	u8 *stream = (u8 *)atr_input;
+	u8 int_key[44];		/* upper-most bit unused */
+	u8 hash_str[46];	/* upper-most 2 bits unused */
+	u16 hash_result = 0;
+	u16 tmp = 0;
+	int i, j, k, h;
+
+	(void) memset(&tmp_key, 0, sizeof (tmp_key));
+	/* First load the temporary key stream */
+	for (i = 0; i < 11; i++)
+		tmp_key.key[i] = key;
+
+	/*
+	 * Set the interim key for the hashing.  Bit 352 is unused, so we must
+	 * shift and compensate when building the key.
+	 */
+	int_key[0] = tmp_key.key_stream[0] >> 1;
+	for (i = 1, j = 0; i < 44; i++) {
+		int_key[i] = (tmp_key.key_stream[j] & 0x1) << 7;
+		j++;
+		int_key[i] |= tmp_key.key_stream[j] >> 1;
+	}
+
+	/*
+	 * Set the interim bit string for the hashing.  Bits 368 and 367 are
+	 * unused, so shift and compensate when building the string.
+	 */
+	hash_str[0] = (stream[40] & 0x7f) >> 1;
+	for (i = 1, j = 40; i < 46; i++) {
+		hash_str[i] = (stream[j] & 0x1) << 7;
+		j++;
+		if (j > 41)
+			j = 0;
+		hash_str[i] |= stream[j] >> 1;
+	}
+
+	/*
+	 * Now compute the hash.  i is the index into hash_str, j is into our
+	 * key stream, k is counting the number of bits, and h interates within
+	 * each byte.
+	 */
+	for (i = 45, j = 43, k = 0; k < 351 && i >= 2 && j >= 0; i--, j--) {
+		for (h = 0; h < 8 && k < 351; h++, k++) {
+			if ((int_key[j] >> h) & 0x1) {
+				/*
+				 * Key bit is set, XOR in the current 16-bit
+				 * string.  Example of processing:
+				 *	h = 0,
+				 *	tmp = (hash_str[i - 2] & 0 << 16) |
+				 *		(hash_str[i - 1] & 0xff << 8) |
+				 *		(hash_str[i] & 0xff >> 0)
+				 *	So tmp = hash_str[15 + k:k], since the
+				 *	i + 2 clause rolls off the 16-bit value
+				 *	h = 7,
+				 *	tmp = (hash_str[i - 2] & 0x7f << 9) |
+				 *		(hash_str[i - 1] & 0xff << 1) |
+				 *		(hash_str[i] & 0x80 >> 7)
+				 */
+				tmp = ((hash_str[i] & (0xff << h)) >> h);
+				tmp |= ((hash_str[i - 1] & 0xff) << (8 - h));
+				tmp |= (hash_str[i - 2] & (0xff >> (8 - h)))
+				    << (16 - h);
+				hash_result ^= tmp;
+			}
+		}
+	}
+
+	return (hash_result);
+}
+
+/*
+ * ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream
+ * @input: input stream to modify
+ * @vlan: the VLAN id to load
+ */
+s32
+ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan)
+{
+	input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] = vlan >> 8;
+	input->byte_stream[IXGBE_ATR_VLAN_OFFSET] = vlan & 0xff;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address
+ * @input: input stream to modify
+ * @src_addr: the IP address to load
+ */
+s32
+ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr)
+{
+	input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] = src_addr >> 24;
+	input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] =
+	    (src_addr >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] =
+	    (src_addr >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET] = src_addr & 0xff;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address
+ * @input: input stream to modify
+ * @dst_addr: the IP address to load
+ */
+s32
+ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr)
+{
+	input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] = dst_addr >> 24;
+	input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] =
+	    (dst_addr >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] =
+	    (dst_addr >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET] = dst_addr & 0xff;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address
+ * @input: input stream to modify
+ * @src_addr_1: the first 4 bytes of the IP address to load
+ * @src_addr_2: the second 4 bytes of the IP address to load
+ * @src_addr_3: the third 4 bytes of the IP address to load
+ * @src_addr_4: the fourth 4 bytes of the IP address to load
+ */
+s32
+ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
+    u32 src_addr_1, u32 src_addr_2, u32 src_addr_3, u32 src_addr_4)
+{
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] =
+	    (src_addr_4 >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] =
+	    (src_addr_4 >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] = src_addr_4 >> 24;
+
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4] = src_addr_3 & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] =
+	    (src_addr_3 >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] =
+	    (src_addr_3 >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] = src_addr_3 >> 24;
+
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8] = src_addr_2 & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] =
+	    (src_addr_2 >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] =
+	    (src_addr_2 >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] = src_addr_2 >> 24;
+
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12] = src_addr_1 & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] =
+	    (src_addr_1 >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] =
+	    (src_addr_1 >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] = src_addr_1 >> 24;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address
+ * @input: input stream to modify
+ * @dst_addr_1: the first 4 bytes of the IP address to load
+ * @dst_addr_2: the second 4 bytes of the IP address to load
+ * @dst_addr_3: the third 4 bytes of the IP address to load
+ * @dst_addr_4: the fourth 4 bytes of the IP address to load
+ */
+s32
+ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
+    u32 dst_addr_1, u32 dst_addr_2, u32 dst_addr_3, u32 dst_addr_4)
+{
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] =
+	    (dst_addr_4 >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] =
+	    (dst_addr_4 >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] = dst_addr_4 >> 24;
+
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4] = dst_addr_3 & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] =
+	    (dst_addr_3 >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] =
+	    (dst_addr_3 >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] = dst_addr_3 >> 24;
+
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8] = dst_addr_2 & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] =
+	    (dst_addr_2 >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] =
+	    (dst_addr_2 >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] = dst_addr_2 >> 24;
+
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12] = dst_addr_1 & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] =
+	    (dst_addr_1 >> 8) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] =
+	    (dst_addr_1 >> 16) & 0xff;
+	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] = dst_addr_1 >> 24;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_src_port_82599 - Sets the source port
+ * @input: input stream to modify
+ * @src_port: the source port to load
+ */
+s32
+ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port)
+{
+	input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1] = src_port >> 8;
+	input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] = src_port & 0xff;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_dst_port_82599 - Sets the destination port
+ * @input: input stream to modify
+ * @dst_port: the destination port to load
+ */
+s32
+ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port)
+{
+	input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1] = dst_port >> 8;
+	input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] = dst_port & 0xff;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_flex_byte_82599 - Sets the flexible bytes
+ * @input: input stream to modify
+ * @flex_bytes: the flexible bytes to load
+ */
+s32
+ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte)
+{
+	input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] = flex_byte >> 8;
+	input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET] = flex_byte & 0xff;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool
+ * @input: input stream to modify
+ * @vm_pool: the Virtual Machine pool to load
+ */
+s32
+ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool)
+{
+	input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type
+ * @input: input stream to modify
+ * @l4type: the layer 4 type value to load
+ */
+s32
+ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type)
+{
+	input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET] = l4type;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_vlan_id_82599 - Gets the VLAN id from the ATR input stream
+ * @input: input stream to search
+ * @vlan: the VLAN id to load
+ */
+s32
+ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan)
+{
+	*vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET];
+	*vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_src_ipv4_82599 - Gets the source IPv4 address
+ * @input: input stream to search
+ * @src_addr: the IP address to load
+ */
+s32
+ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr)
+{
+	*src_addr = input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET];
+	*src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] << 8;
+	*src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] << 16;
+	*src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] << 24;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_dst_ipv4_82599 - Gets the destination IPv4 address
+ * @input: input stream to search
+ * @dst_addr: the IP address to load
+ */
+s32
+ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr)
+{
+	*dst_addr = input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET];
+	*dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] << 8;
+	*dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] << 16;
+	*dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] << 24;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_src_ipv6_82599 - Gets the source IPv6 address
+ * @input: input stream to search
+ * @src_addr_1: the first 4 bytes of the IP address to load
+ * @src_addr_2: the second 4 bytes of the IP address to load
+ * @src_addr_3: the third 4 bytes of the IP address to load
+ * @src_addr_4: the fourth 4 bytes of the IP address to load
+ */
+s32
+ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
+    u32 *src_addr_1, u32 *src_addr_2, u32 *src_addr_3, u32 *src_addr_4)
+{
+	*src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12];
+	*src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] << 8;
+	*src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] << 16;
+	*src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] << 24;
+
+	*src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8];
+	*src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] << 8;
+	*src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] << 16;
+	*src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] << 24;
+
+	*src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4];
+	*src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] << 8;
+	*src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] << 16;
+	*src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] << 24;
+
+	*src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET];
+	*src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] << 8;
+	*src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] << 16;
+	*src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] << 24;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address
+ * @input: input stream to search
+ * @dst_addr_1: the first 4 bytes of the IP address to load
+ * @dst_addr_2: the second 4 bytes of the IP address to load
+ * @dst_addr_3: the third 4 bytes of the IP address to load
+ * @dst_addr_4: the fourth 4 bytes of the IP address to load
+ */
+s32
+ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
+    u32 *dst_addr_1, u32 *dst_addr_2, u32 *dst_addr_3, u32 *dst_addr_4)
+{
+	*dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12];
+	*dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8;
+	*dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16;
+	*dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] << 24;
+
+	*dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8];
+	*dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] << 8;
+	*dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] << 16;
+	*dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] << 24;
+
+	*dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4];
+	*dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] << 8;
+	*dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] << 16;
+	*dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] << 24;
+
+	*dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET];
+	*dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] << 8;
+	*dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] << 16;
+	*dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] << 24;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_src_port_82599 - Gets the source port
+ * @input: input stream to modify
+ * @src_port: the source port to load
+ *
+ * Even though the input is given in big-endian, the FDIRPORT registers
+ * expect the ports to be programmed in little-endian.  Hence the need to swap
+ * endianness when retrieving the data.  This can be confusing since the
+ * internal hash engine expects it to be big-endian.
+ */
+s32
+ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port)
+{
+	*src_port = input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] << 8;
+	*src_port |= input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1];
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_dst_port_82599 - Gets the destination port
+ * @input: input stream to modify
+ * @dst_port: the destination port to load
+ *
+ * Even though the input is given in big-endian, the FDIRPORT registers
+ * expect the ports to be programmed in little-endian.  Hence the need to swap
+ * endianness when retrieving the data.  This can be confusing since the
+ * internal hash engine expects it to be big-endian.
+ */
+s32
+ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port)
+{
+	*dst_port = input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] << 8;
+	*dst_port |= input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1];
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_flex_byte_82599 - Gets the flexible bytes
+ * @input: input stream to modify
+ * @flex_bytes: the flexible bytes to load
+ */
+s32
+ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte)
+{
+	*flex_byte = input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET];
+	*flex_byte |= input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] << 8;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool
+ * @input: input stream to modify
+ * @vm_pool: the Virtual Machine pool to load
+ */
+s32
+ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool)
+{
+	*vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET];
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type
+ * @input: input stream to modify
+ * @l4type: the layer 4 type value to load
+ */
+s32
+ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type)
+{
+	*l4type = input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET];
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter
+ * @hw: pointer to hardware structure
+ * @stream: input bitstream
+ * @queue: queue index to direct traffic to
+ */
+s32
+ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
+    struct ixgbe_atr_input *input, u8 queue)
+{
+	u64  fdirhashcmd;
+	u64  fdircmd;
+	u32  fdirhash;
+	u16  bucket_hash, sig_hash;
+	u8   l4type;
+
+	bucket_hash = ixgbe_atr_compute_hash_82599(input,
+	    IXGBE_ATR_BUCKET_HASH_KEY);
+
+	/* bucket_hash is only 15 bits */
+	bucket_hash &= IXGBE_ATR_HASH_MASK;
+
+	sig_hash = ixgbe_atr_compute_hash_82599(input,
+	    IXGBE_ATR_SIGNATURE_HASH_KEY);
+
+	/* Get the l4type in order to program FDIRCMD properly */
+	/* lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6 */
+	(void) ixgbe_atr_get_l4type_82599(input, &l4type);
+
+	/*
+	 * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
+	 * is for FDIRCMD.  Then do a 64-bit register write from FDIRHASH.
+	 */
+	fdirhash = sig_hash << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash;
+
+	fdircmd = (IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
+	    IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN);
+
+	switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
+	case IXGBE_ATR_L4TYPE_TCP:
+		fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP;
+		break;
+	case IXGBE_ATR_L4TYPE_UDP:
+		fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP;
+		break;
+	case IXGBE_ATR_L4TYPE_SCTP:
+		fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP;
+		break;
+	default:
+		DEBUGOUT(" Error on l4type input\n");
+		return (IXGBE_ERR_CONFIG);
+	}
+
+	if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK)
+		fdircmd |= IXGBE_FDIRCMD_IPV6;
+
+	fdircmd |= ((u64)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT);
+	fdirhashcmd = ((fdircmd << 32) | fdirhash);
+
+	DEBUGOUT2("Tx Queue=%x hash=%x\n", queue, fdirhash & 0x7FFF7FFF);
+	IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
+ * @hw: pointer to hardware structure
+ * @input: input bitstream
+ * @queue: queue index to direct traffic to
+ *
+ * Note that the caller to this function must lock before calling, since the
+ * hardware writes must be protected from one another.
+ */
+s32
+ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
+    struct ixgbe_atr_input *input, u16 soft_id, u8 queue)
+{
+	u32 fdircmd = 0;
+	u32 fdirhash;
+	u32 src_ipv4, dst_ipv4;
+	u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4;
+	u16 src_port, dst_port, vlan_id, flex_bytes;
+	u16 bucket_hash;
+	u8  l4type;
+
+	/* Get our input values */
+	(void) ixgbe_atr_get_l4type_82599(input, &l4type);
+
+	/*
+	 * Check l4type formatting, and bail out before we touch the hardware
+	 * if there's a configuration issue
+	 */
+	switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
+	case IXGBE_ATR_L4TYPE_TCP:
+		fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP;
+		break;
+	case IXGBE_ATR_L4TYPE_UDP:
+		fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP;
+		break;
+	case IXGBE_ATR_L4TYPE_SCTP:
+		fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP;
+		break;
+	default:
+		DEBUGOUT(" Error on l4type input\n");
+		return (IXGBE_ERR_CONFIG);
+	}
+
+	bucket_hash = ixgbe_atr_compute_hash_82599(input,
+	    IXGBE_ATR_BUCKET_HASH_KEY);
+
+	/* bucket_hash is only 15 bits */
+	bucket_hash &= IXGBE_ATR_HASH_MASK;
+
+	(void) ixgbe_atr_get_vlan_id_82599(input, &vlan_id);
+	(void) ixgbe_atr_get_src_port_82599(input, &src_port);
+	(void) ixgbe_atr_get_dst_port_82599(input, &dst_port);
+	(void) ixgbe_atr_get_flex_byte_82599(input, &flex_bytes);
+
+	fdirhash = soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash;
+
+	/* Now figure out if we're IPv4 or IPv6 */
+	if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK) {
+		/* IPv6 */
+		(void) ixgbe_atr_get_src_ipv6_82599(input, &src_ipv6_1,
+		    &src_ipv6_2, &src_ipv6_3, &src_ipv6_4);
+
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), src_ipv6_1);
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(1), src_ipv6_2);
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), src_ipv6_3);
+		/* The last 4 bytes is the same register as IPv4 */
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv6_4);
+
+		fdircmd |= IXGBE_FDIRCMD_IPV6;
+		fdircmd |= IXGBE_FDIRCMD_IPv6DMATCH;
+	} else {
+		/* IPv4 */
+		(void) ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4);
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4);
+
+	}
+
+	(void) ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4);
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRIPDA, dst_ipv4);
+
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id |
+	    (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT)));
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port |
+	    (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
+
+	fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW;
+	fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE;
+	fdircmd |= IXGBE_FDIRCMD_LAST;
+	fdircmd |= IXGBE_FDIRCMD_QUEUE_EN;
+	fdircmd |= queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
+
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
+ * @hw: pointer to hardware structure
+ * @reg: analog register to read
+ * @val: read value
+ *
+ * Performs read operation to Omer analog register specified.
+ */
+s32
+ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
+{
+	u32  core_ctl;
+
+	IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD |
+	    (reg << 8));
+	IXGBE_WRITE_FLUSH(hw);
+	usec_delay(10);
+	core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL);
+	*val = (u8)core_ctl;
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
+ * @hw: pointer to hardware structure
+ * @reg: atlas register to write
+ * @val: value to write
+ *
+ * Performs write operation to Omer analog register specified.
+ */
+s32
+ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
+{
+	u32  core_ctl;
+
+	core_ctl = (reg << 8) | val;
+	IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl);
+	IXGBE_WRITE_FLUSH(hw);
+	usec_delay(10);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_start_hw_rev_1_82599 - Prepare hardware for Tx/Rx
+ * @hw: pointer to hardware structure
+ *
+ * Starts the hardware using the generic start_hw function.
+ * Then performs revision-specific operations:
+ * Clears the rate limiter registers.
+ */
+s32
+ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw)
+{
+	u32 q_num;
+	s32 ret_val = IXGBE_SUCCESS;
+
+	ret_val = ixgbe_start_hw_generic(hw);
+
+	/* Clear the rate limiters */
+	for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
+		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
+		IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
+	}
+	IXGBE_WRITE_FLUSH(hw);
+
+	return (ret_val);
+}
+
+/*
+ * ixgbe_identify_phy_82599 - Get physical layer module
+ * @hw: pointer to hardware structure
+ *
+ * Determines the physical layer module found on the current adapter.
+ * If PHY already detected, maintains current PHY type in hw struct,
+ * otherwise executes the PHY detection routine.
+ */
+s32
+ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+{
+	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+
+	/* Detect PHY if not unknown - returns success if already detected. */
+	status = ixgbe_identify_phy_generic(hw);
+	if (status != IXGBE_SUCCESS)
+		status = ixgbe_identify_sfp_module_generic(hw);
+	/* Set PHY type none if no PHY detected */
+	if (hw->phy.type == ixgbe_phy_unknown) {
+		hw->phy.type = ixgbe_phy_none;
+		status = IXGBE_SUCCESS;
+	}
+
+	/* Return error if SFP module has been detected but is not supported */
+	if (hw->phy.type == ixgbe_phy_sfp_unsupported)
+		status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+
+	return (status);
+}
+
+/*
+ * ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
+ * @hw: pointer to hardware structure
+ *
+ * Determines physical layer capabilities of the current configuration.
+ */
+u32
+ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
+{
+	u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+	u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
+	u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+	u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+	u16 ext_ability = 0;
+	u8 comp_codes_10g = 0;
+
+	hw->phy.ops.identify(hw);
+
+	if (hw->phy.type == ixgbe_phy_tn ||
+	    hw->phy.type == ixgbe_phy_cu_unknown) {
+		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
+		    IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
+		if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+		if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+		if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+		goto out;
+	}
+
+	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+	case IXGBE_AUTOC_LMS_1G_AN:
+	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+		if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) {
+			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
+			    IXGBE_PHYSICAL_LAYER_1000BASE_BX;
+			goto out;
+		} else
+			/* SFI mode so read SFP module */
+			goto sfp_check;
+	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+		if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4)
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+		else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4)
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+		goto out;
+	case IXGBE_AUTOC_LMS_10G_SERIAL:
+		if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) {
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+			goto out;
+		} else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)
+			goto sfp_check;
+		break;
+	case IXGBE_AUTOC_LMS_KX4_KX_KR:
+	case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
+		if (autoc & IXGBE_AUTOC_KX_SUPP)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+		if (autoc & IXGBE_AUTOC_KX4_SUPP)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+		if (autoc & IXGBE_AUTOC_KR_SUPP)
+			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+		goto out;
+	default:
+		goto out;
+	}
+
+sfp_check:
+	/*
+	 * SFP check must be done last since DA modules are sometimes used to
+	 * test KR mode -  we need to id KR mode correctly before SFP module.
+	 * Call identify_sfp because the pluggable module may have changed
+	 */
+	hw->phy.ops.identify_sfp(hw);
+	if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
+		goto out;
+
+	switch (hw->phy.type) {
+	case ixgbe_phy_tw_tyco:
+	case ixgbe_phy_tw_unknown:
+		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+		break;
+	case ixgbe_phy_sfp_avago:
+	case ixgbe_phy_sfp_ftl:
+	case ixgbe_phy_sfp_intel:
+	case ixgbe_phy_sfp_unknown:
+		hw->phy.ops.read_i2c_eeprom(hw,
+		    IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
+		if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+		break;
+	default:
+		break;
+	}
+
+out:
+	return (physical_layer);
+}
+
+/*
+ * ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
+ * @hw: pointer to hardware structure
+ * @regval: register value to write to RXCTRL
+ *
+ * Enables the Rx DMA unit for 82599
+ */
+s32
+ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
+{
+#define	IXGBE_MAX_SECRX_POLL	30
+	int i;
+	int secrxreg;
+
+	/*
+	 * Workaround for 82599 silicon errata when enabling the Rx datapath.
+	 * If traffic is incoming before we enable the Rx unit, it could hang
+	 * the Rx DMA unit.  Therefore, make sure the security engine is
+	 * completely disabled prior to enabling the Rx unit.
+	 */
+	secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+	secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+	for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
+		secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
+		if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
+			break;
+		else
+			/* Use interrupt-safe sleep just in case */
+			usec_delay(10);
+	}
+
+	/* For informational purposes only */
+	if (i >= IXGBE_MAX_SECRX_POLL)
+		DEBUGOUT("Rx unit being enabled before security "
+		    "path fully disabled.	Continuing with init.\n");
+
+	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+	secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+	secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_get_device_caps_82599 - Get additional device capabilities
+ * @hw: pointer to hardware structure
+ * @device_caps: the EEPROM word with the extra device capabilities
+ *
+ * This function will read the EEPROM location for the device capabilities,
+ * and return the word through device_caps.
+ */
+s32
+ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
+{
+	hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_get_san_mac_addr_offset_82599 - SAN MAC address offset for 82599
+ * @hw: pointer to hardware structure
+ * @san_mac_offset: SAN MAC address offset
+ *
+ * This function will read the EEPROM location for the SAN MAC address
+ * pointer, and returns the value at that location.  This is used in both
+ * get and set mac_addr routines.
+ */
+s32
+ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw, u16 *san_mac_offset)
+{
+	/*
+	 * First read the EEPROM pointer to see if the MAC addresses are
+	 * available.
+	 */
+	hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_get_san_mac_addr_82599 - SAN MAC address retrieval for 82599
+ * @hw: pointer to hardware structure
+ * @san_mac_addr: SAN MAC address
+ *
+ * Reads the SAN MAC address from the EEPROM, if it's available.  This is
+ * per-port, so set_lan_id() must be called before reading the addresses.
+ * set_lan_id() is called by identify_sfp(), but this cannot be relied
+ * upon for non-SFP connections, so we must call it here.
+ */
+s32
+ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr)
+{
+	u16 san_mac_data, san_mac_offset;
+	u8 i;
+
+	/*
+	 * First read the EEPROM pointer to see if the MAC addresses are
+	 * available.  If they're not, no point in calling set_lan_id() here.
+	 */
+	(void) ixgbe_get_san_mac_addr_offset_82599(hw, &san_mac_offset);
+
+	if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
+		/*
+		 * No addresses available in this EEPROM.  It's not an
+		 * error though, so just wipe the local address and return.
+		 */
+		for (i = 0; i < 6; i++)
+			san_mac_addr[i] = 0xFF;
+
+		goto san_mac_addr_out;
+	}
+
+	/* make sure we know which port we need to program */
+	hw->mac.ops.set_lan_id(hw);
+	/* apply the port offset to the address offset */
+	(hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
+	    (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
+	for (i = 0; i < 3; i++) {
+		hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data);
+		san_mac_addr[i * 2] = (u8)(san_mac_data);
+		san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8);
+		san_mac_offset++;
+	}
+
+san_mac_addr_out:
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_set_san_mac_addr_82599 - Write the SAN MAC address to the EEPROM
+ * @hw: pointer to hardware structure
+ * @san_mac_addr: SAN MAC address
+ *
+ * Write a SAN MAC address to the EEPROM.
+ */
+s32
+ixgbe_set_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr)
+{
+	s32 status = IXGBE_SUCCESS;
+	u16 san_mac_data, san_mac_offset;
+	u8 i;
+
+	/* Look for SAN mac address pointer.  If not defined, return */
+	(void) ixgbe_get_san_mac_addr_offset_82599(hw, &san_mac_offset);
+
+	if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
+		status = IXGBE_ERR_NO_SAN_ADDR_PTR;
+		goto san_mac_addr_out;
+	}
+
+	/* Make sure we know which port we need to write */
+	hw->mac.ops.set_lan_id(hw);
+	/* Apply the port offset to the address offset */
+	(hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
+	    (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
+
+	for (i = 0; i < 3; i++) {
+		san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8);
+		san_mac_data |= (u16)(san_mac_addr[i * 2]);
+		hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data);
+		san_mac_offset++;
+	}
+
+san_mac_addr_out:
+	return (status);
+}
--- a/usr/src/uts/common/io/ixgbe/ixgbe_api.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_api.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,16 +23,16 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
-/* IntelVersion: 1.99 v2008-09-12 */
+/* IntelVersion: 1.117 v2-7-8_2009-4-7 */
 
 #include "ixgbe_api.h"
 #include "ixgbe_common.h"
-#ident "$Id: ixgbe_api.c,v 1.99 2008/08/22 16:30:26 mrchilak Exp $"
 
 extern s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw);
+extern s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw);
 
 /*
  * ixgbe_init_shared_code - Initialize the shared code
@@ -44,7 +44,7 @@
  * memset to 0 prior to calling this function.  The following fields in
  * hw structure should be filled in prior to calling this function:
  * hw_addr, back, device_id, vendor_id, subsystem_device_id,
- *  subsystem_vendor_id, and revision_id
+ * subsystem_vendor_id, and revision_id
  */
 s32
 ixgbe_init_shared_code(struct ixgbe_hw *hw)
@@ -60,6 +60,9 @@
 	case ixgbe_mac_82598EB:
 		status = ixgbe_init_ops_82598(hw);
 		break;
+	case ixgbe_mac_82599EB:
+		status = ixgbe_init_ops_82599(hw);
+		break;
 	default:
 		status = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
 		break;
@@ -84,6 +87,8 @@
 
 	if (hw->vendor_id == IXGBE_INTEL_VENDOR_ID) {
 		switch (hw->device_id) {
+		case IXGBE_DEV_ID_82598:
+		case IXGBE_DEV_ID_82598_BX:
 		case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
 		case IXGBE_DEV_ID_82598AF_DUAL_PORT:
 		case IXGBE_DEV_ID_82598AT:
@@ -95,6 +100,13 @@
 		case IXGBE_DEV_ID_82598EB_SFP_LOM:
 			hw->mac.type = ixgbe_mac_82598EB;
 			break;
+		case IXGBE_DEV_ID_82599_KX4:
+		case IXGBE_DEV_ID_82599_KX4_SIK:
+		case IXGBE_DEV_ID_82599_SFP:
+		case IXGBE_DEV_ID_82599_SPW:
+		case IXGBE_DEV_ID_82599_CX4:
+			hw->mac.type = ixgbe_mac_82599EB;
+			break;
 		default:
 			ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
 			break;
@@ -198,6 +210,49 @@
 }
 
 /*
+ * ixgbe_get_san_mac_addr - Get SAN MAC address
+ * @hw: pointer to hardware structure
+ * @san_mac_addr: SAN MAC address
+ *
+ * Reads the SAN MAC address from the EEPROM, if it's available.  This is
+ * per-port, so set_lan_id() must be called before reading the addresses.
+ */
+s32
+ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr)
+{
+	return ixgbe_call_func(hw, hw->mac.ops.get_san_mac_addr,
+	    (hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED);
+}
+
+/*
+ * ixgbe_set_san_mac_addr - Write a SAN MAC address
+ * @hw: pointer to hardware structure
+ * @san_mac_addr: SAN MAC address
+ *
+ * Writes A SAN MAC address to the EEPROM.
+ */
+s32
+ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr)
+{
+	return ixgbe_call_func(hw, hw->mac.ops.set_san_mac_addr,
+	    (hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED);
+}
+
+/*
+ * ixgbe_get_device_caps - Get additional device capabilities
+ * @hw: pointer to hardware structure
+ * @device_caps: the EEPROM word for device capabilities
+ *
+ * Reads the extra device capabilities from the EEPROM
+ */
+s32
+ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps)
+{
+	return ixgbe_call_func(hw, hw->mac.ops.get_device_caps,
+	    (hw, device_caps), IXGBE_NOT_IMPLEMENTED);
+}
+
+/*
  * ixgbe_get_bus_info - Set PCI bus info
  * @hw: pointer to hardware structure
  *
@@ -333,6 +388,9 @@
 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
 	u16 *phy_data)
 {
+	if (hw->phy.id == 0)
+		(void) ixgbe_identify_phy(hw);
+
 	return ixgbe_call_func(hw, hw->phy.ops.read_reg, (hw, reg_addr,
 	    device_type, phy_data), IXGBE_NOT_IMPLEMENTED);
 }
@@ -348,6 +406,9 @@
 s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
     u16 phy_data)
 {
+	if (hw->phy.id == 0)
+		(void) ixgbe_identify_phy(hw);
+
 	return ixgbe_call_func(hw, hw->phy.ops.write_reg, (hw, reg_addr,
 	    device_type, phy_data), IXGBE_NOT_IMPLEMENTED);
 }
@@ -584,6 +645,22 @@
 }
 
 /*
+ * ixgbe_insert_mac_addr - Find a RAR for this mac address
+ * @hw: pointer to hardware structure
+ * @addr: Address to put into receive address register
+ * @vmdq: VMDq pool to assign
+ *
+ * Puts an ethernet address into a receive address register, or
+ * finds the rar that it is aleady in; adds to the pool list
+ */
+s32
+ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
+{
+	return ixgbe_call_func(hw, hw->mac.ops.insert_mac_addr,
+	    (hw, addr, vmdq), IXGBE_NOT_IMPLEMENTED);
+}
+
+/*
  * ixgbe_set_rar - Set Rx address register
  * @hw: pointer to hardware structure
  * @index: Receive address register to write
@@ -763,16 +840,16 @@
 }
 
 /*
- * ixgbe_setup_fc - Set flow control
+ * ixgbe_fc_enable - Enable flow control
  * @hw: pointer to hardware structure
  * @packetbuf_num: packet buffer number (0-7)
  *
  * Configures the flow control settings based on SW configuration.
  */
 s32
-ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
+ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
 {
-	return ixgbe_call_func(hw, hw->mac.ops.setup_fc, (hw, packetbuf_num),
+	return ixgbe_call_func(hw, hw->mac.ops.fc_enable, (hw, packetbuf_num),
 	    IXGBE_NOT_IMPLEMENTED);
 }
 
@@ -821,6 +898,54 @@
 }
 
 /*
+ * ixgbe_read_i2c_byte - Reads 8 bit word over I2C at specified device address
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface.
+ */
+s32
+ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
+    u8 *data)
+{
+	return ixgbe_call_func(hw, hw->phy.ops.read_i2c_byte, (hw, byte_offset,
+	    dev_addr, data), IXGBE_NOT_IMPLEMENTED);
+}
+
+/*
+ * ixgbe_write_i2c_byte - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface
+ * at a specified device address.
+ */
+s32
+ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
+    u8 data)
+{
+	return ixgbe_call_func(hw, hw->phy.ops.write_i2c_byte,
+	    (hw, byte_offset, dev_addr, data), IXGBE_NOT_IMPLEMENTED);
+}
+
+/*
+ * ixgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to write
+ * @eeprom_data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface.
+ */
+s32
+ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data)
+{
+	return ixgbe_call_func(hw, hw->phy.ops.write_i2c_eeprom,
+	    (hw, byte_offset, eeprom_data), IXGBE_NOT_IMPLEMENTED);
+}
+
+/*
  * ixgbe_read_i2c_eeprom - Reads 8 bit EEPROM word over I2C interface
  * @hw: pointer to hardware structure
  * @byte_offset: EEPROM byte offset to read
@@ -832,8 +957,7 @@
 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data)
 {
 	return ixgbe_call_func(hw, hw->phy.ops.read_i2c_eeprom,
-	    (hw, byte_offset, eeprom_data),
-	    IXGBE_NOT_IMPLEMENTED);
+	    (hw, byte_offset, eeprom_data), IXGBE_NOT_IMPLEMENTED);
 }
 
 /*
@@ -842,9 +966,23 @@
  *
  * Determines physical layer capabilities of the current configuration.
  */
-s32
+u32
 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw)
 {
 	return ixgbe_call_func(hw, hw->mac.ops.get_supported_physical_layer,
 	    (hw), IXGBE_NOT_IMPLEMENTED);
 }
+
+/*
+ * ixgbe_enable_rx_dma - Enables Rx DMA unit, dependant on device specifics
+ * @hw: pointer to hardware structure
+ * @regval: bitfield to write to the Rx DMA register
+ *
+ * Enables the Rx DMA unit of the device.
+ */
+s32
+ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval)
+{
+	return ixgbe_call_func(hw, hw->mac.ops.enable_rx_dma,
+	    (hw, regval), IXGBE_NOT_IMPLEMENTED);
+}
--- a/usr/src/uts/common/io/ixgbe/ixgbe_api.h	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_api.h	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,16 +23,15 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
-/* IntelVersion: 1.63 v2008-09-12 */
+/* IntelVersion: 1.73 v2-7-8_2009-4-7  */
 
 #ifndef _IXGBE_API_H
 #define	_IXGBE_API_H
 
 #include "ixgbe_type.h"
-#ident "$Id: ixgbe_api.h,v 1.63 2008/08/21 18:03:40 mrchilak Exp $"
 
 s32 ixgbe_init_shared_code(struct ixgbe_hw *hw);
 
@@ -79,6 +78,7 @@
 s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val);
 s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw);
 
+s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
 s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
     u32 enable_addr);
 s32 ixgbe_clear_rar(struct ixgbe_hw *hw, u32 index);
@@ -95,7 +95,7 @@
 s32 ixgbe_clear_vfta(struct ixgbe_hw *hw);
 s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
 
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
+s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num);
 
 void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr);
 s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw,
@@ -104,6 +104,48 @@
 s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val);
 s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw);
 s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data);
-s32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw);
+u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw);
+s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval);
+s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
+s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc);
+s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
+s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
+    struct ixgbe_atr_input *input, u8 queue);
+s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
+    struct ixgbe_atr_input *input, u16 soft_id, u8 queue);
+u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key);
+s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan_id);
+s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr);
+s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr);
+s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, u32 src_addr_1,
+    u32 src_addr_2, u32 src_addr_3, u32 src_addr_4);
+s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, u32 dst_addr_1,
+    u32 dst_addr_2, u32 dst_addr_3, u32 dst_addr_4);
+s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port);
+s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port);
+s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte);
+s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool);
+s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type);
+s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan_id);
+s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr);
+s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr);
+s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, u32 *src_addr_1,
+    u32 *src_addr_2, u32 *src_addr_3, u32 *src_addr_4);
+s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, u32 *dst_addr_1,
+    u32 *dst_addr_2, u32 *dst_addr_3, u32 *dst_addr_4);
+s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port);
+s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port);
+s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input,
+    u16 *flex_byte);
+s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool);
+s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type);
+s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
+    u8 *data);
+s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
+    u8 data);
+s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data);
+s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
+s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
+s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps);
 
 #endif /* _IXGBE_API_H */
--- a/usr/src/uts/common/io/ixgbe/ixgbe_buf.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_buf.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -22,11 +22,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include "ixgbe_sw.h"
 
@@ -803,14 +802,9 @@
 		rcb->free_rtn.free_arg = (char *)rcb;
 
 		rcb->mp = desballoc((unsigned char *)
-		    rx_buf->address - IPHDR_ALIGN_ROOM,
-		    rx_buf->size + IPHDR_ALIGN_ROOM,
+		    rx_buf->address,
+		    rx_buf->size,
 		    0, &rcb->free_rtn);
-
-		if (rcb->mp != NULL) {
-			rcb->mp->b_rptr += IPHDR_ALIGN_ROOM;
-			rcb->mp->b_wptr += IPHDR_ALIGN_ROOM;
-		}
 	}
 
 	return (IXGBE_SUCCESS);
--- a/usr/src/uts/common/io/ixgbe/ixgbe_common.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_common.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,6 +1,7 @@
 /*
  * CDDL HEADER START
  *
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -20,19 +21,14 @@
  */
 
 /*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-/* IntelVersion: 1.173 v2008-09-12 */
+/* IntelVersion: 1.199 v2-7-8_2009-4-7 */
 
 #include "ixgbe_common.h"
 #include "ixgbe_api.h"
-#ident "$Id: ixgbe_common.c,v 1.173 2008/09/02 18:20:18 mrchilak Exp $"
 
 static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw);
 static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
@@ -48,11 +44,7 @@
 static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
 static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw);
 
-static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
-static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
 static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
-void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
-void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
 
 /*
  * ixgbe_init_ops_generic - Inits function ptrs
@@ -86,19 +78,22 @@
 	mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic;
 	mac->ops.get_media_type = NULL;
 	mac->ops.get_supported_physical_layer = NULL;
+	mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic;
 	mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic;
 	mac->ops.stop_adapter = &ixgbe_stop_adapter_generic;
 	mac->ops.get_bus_info = &ixgbe_get_bus_info_generic;
+	mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie;
 
 	/* LEDs */
 	mac->ops.led_on = &ixgbe_led_on_generic;
 	mac->ops.led_off = &ixgbe_led_off_generic;
-	mac->ops.blink_led_start = NULL;
-	mac->ops.blink_led_stop = NULL;
+	mac->ops.blink_led_start = &ixgbe_blink_led_start_generic;
+	mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic;
 
 	/* RAR, Multicast, VLAN */
 	mac->ops.set_rar = &ixgbe_set_rar_generic;
 	mac->ops.clear_rar = &ixgbe_clear_rar_generic;
+	mac->ops.insert_mac_addr = NULL;
 	mac->ops.set_vmdq = NULL;
 	mac->ops.clear_vmdq = NULL;
 	mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic;
@@ -111,7 +106,7 @@
 	mac->ops.init_uta_tables = NULL;
 
 	/* Flow Control */
-	mac->ops.setup_fc = NULL;
+	mac->ops.fc_enable = &ixgbe_fc_enable_generic;
 
 	/* Link */
 	mac->ops.get_link_capabilities = NULL;
@@ -139,24 +134,14 @@
 	/* Set the media type */
 	hw->phy.media_type = hw->mac.ops.get_media_type(hw);
 
-	/* Set bus info */
-	hw->mac.ops.get_bus_info(hw);
+	/* PHY ops initialization must be done in reset_hw() */
 
 	/* Identify the PHY */
 	hw->phy.ops.identify(hw);
 
-	/*
-	 * Store MAC address from RAR0, clear receive address registers, and
-	 * clear the multicast table
-	 */
-	hw->mac.ops.init_rx_addrs(hw);
-
 	/* Clear the VLAN filter table */
 	hw->mac.ops.clear_vfta(hw);
 
-	/* Set up link */
-	hw->mac.ops.setup_link(hw);
-
 	/* Clear statistics registers */
 	hw->mac.ops.clear_hw_cntrs(hw);
 
@@ -166,6 +151,9 @@
 	IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
 	IXGBE_WRITE_FLUSH(hw);
 
+	/* Setup flow control */
+	(void) ixgbe_setup_fc(hw, 0);
+
 	/* Clear adapter stopped flag */
 	hw->adapter_stopped = false;
 
@@ -185,13 +173,17 @@
 s32
 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
 {
+	s32 status = IXGBE_SUCCESS;
+
 	/* Reset the hardware */
-	hw->mac.ops.reset_hw(hw);
+	status = hw->mac.ops.reset_hw(hw);
 
-	/* Start the HW */
-	hw->mac.ops.start_hw(hw);
+	if (status == IXGBE_SUCCESS) {
+		/* Start the HW */
+		status = hw->mac.ops.start_hw(hw);
+	}
 
-	return (IXGBE_SUCCESS);
+	return (status);
 }
 
 /*
@@ -217,16 +209,29 @@
 	(void) IXGBE_READ_REG(hw, IXGBE_MRFC);
 	(void) IXGBE_READ_REG(hw, IXGBE_RLEC);
 	(void) IXGBE_READ_REG(hw, IXGBE_LXONTXC);
-	(void) IXGBE_READ_REG(hw, IXGBE_LXONRXC);
 	(void) IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
-	(void) IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+	if (hw->mac.type >= ixgbe_mac_82599EB) {
+		(void) IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
+		(void) IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+	} else {
+		(void) IXGBE_READ_REG(hw, IXGBE_LXONRXC);
+		(void) IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+	}
 
 	for (i = 0; i < 8; i++) {
 		(void) IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
-		(void) IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
 		(void) IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
-		(void) IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
+		if (hw->mac.type >= ixgbe_mac_82599EB) {
+			(void) IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
+			(void) IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
+		} else {
+			(void) IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
+			(void) IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
+		}
 	}
+	if (hw->mac.type >= ixgbe_mac_82599EB)
+		for (i = 0; i < 8; i++)
+			(void) IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
 
 	(void) IXGBE_READ_REG(hw, IXGBE_PRC64);
 	(void) IXGBE_READ_REG(hw, IXGBE_PRC127);
@@ -267,7 +272,12 @@
 		(void) IXGBE_READ_REG(hw, IXGBE_QPRC(i));
 		(void) IXGBE_READ_REG(hw, IXGBE_QBRC(i));
 		(void) IXGBE_READ_REG(hw, IXGBE_QPTC(i));
-		(void) IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+		if (hw->mac.type >= ixgbe_mac_82599EB) {
+			(void) IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
+			(void) IXGBE_READ_REG(hw, IXGBE_QBTC_H(i));
+		} else {
+			(void) IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+		}
 	}
 
 	return (IXGBE_SUCCESS);
@@ -342,6 +352,7 @@
 s32
 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
 {
+	struct ixgbe_mac_info *mac = &hw->mac;
 	u16 link_status;
 
 	hw->bus.type = ixgbe_bus_type_pci_express;
@@ -379,9 +390,35 @@
 		break;
 	}
 
+	mac->ops.set_lan_id(hw);
+
 	return (IXGBE_SUCCESS);
 }
 
+
+/*
+ * ixgbe_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.
+ */
+void
+ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
+{
+	struct ixgbe_bus_info *bus = &hw->bus;
+	u32 reg;
+
+	reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
+	bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
+	bus->lan_id = bus->func;
+
+	/* check for a port swap */
+	reg = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+	if (reg & IXGBE_FACTPS_LFS)
+		bus->func ^= 0x1;
+}
+
 /*
  * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
  * @hw: pointer to hardware structure
@@ -685,11 +722,12 @@
 	IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
 	status = ixgbe_poll_eeprom_eerd_done(hw);
 
-	if (status == IXGBE_SUCCESS)
+	if (status == IXGBE_SUCCESS) {
 		*data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
 		    IXGBE_EEPROM_READ_REG_DATA);
-	else
+	} else {
 		DEBUGOUT("Eeprom read timed out\n");
+	}
 
 out:
 	return (status);
@@ -828,11 +866,14 @@
 		 * was not granted because we don't have access to the EEPROM
 		 */
 		if (i >= timeout) {
-			DEBUGOUT("Driver can't access the Eeprom - Semaphore "
+			DEBUGOUT("SWESMBI Software EEPROM semaphore "
 			    "not granted.\n");
 			ixgbe_release_eeprom_semaphore(hw);
 			status = IXGBE_ERR_EEPROM;
 		}
+	} else {
+		DEBUGOUT("Software semaphore SMBI between device drivers "
+		    "not granted.\n");
 	}
 
 	return (status);
@@ -1308,40 +1349,6 @@
 }
 
 /*
- * ixgbe_enable_rar - Enable Rx address register
- * @hw: pointer to hardware structure
- * @index: index into the RAR table
- *
- * Enables the select receive address register.
- */
-static void
-ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index)
-{
-	u32 rar_high;
-
-	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
-	rar_high |= IXGBE_RAH_AV;
-	IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
-}
-
-/*
- * ixgbe_disable_rar - Disable Rx address register
- * @hw: pointer to hardware structure
- * @index: index into the RAR table
- *
- * Disables the select receive address register.
- */
-static void
-ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index)
-{
-	u32 rar_high;
-
-	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
-	rar_high &= (~IXGBE_RAH_AV);
-	IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
-}
-
-/*
  * ixgbe_init_rx_addrs_generic - Initializes receive address filters.
  * @hw: pointer to hardware structure
  *
@@ -1393,7 +1400,6 @@
 	}
 
 	/* Clear the MTA */
-	hw->addr_ctrl.mc_addr_in_rar_count = 0;
 	hw->addr_ctrl.mta_in_use = 0;
 	IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
 
@@ -1401,11 +1407,12 @@
 	for (i = 0; i < hw->mac.mcft_size; i++)
 		IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
 
-	ixgbe_init_uta_tables(hw);
+	(void) ixgbe_init_uta_tables(hw);
 
 	return (IXGBE_SUCCESS);
 }
 
+
 /*
  * ixgbe_add_uc_addr - Adds a secondary unicast address.
  * @hw: pointer to hardware structure
@@ -1427,8 +1434,7 @@
 	 * else put the controller into promiscuous mode
 	 */
 	if (hw->addr_ctrl.rar_used_count < rar_entries) {
-		rar = hw->addr_ctrl.rar_used_count -
-		    hw->addr_ctrl.mc_addr_in_rar_count;
+		rar = hw->addr_ctrl.rar_used_count;
 		hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
 		DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar);
 		hw->addr_ctrl.rar_used_count++;
@@ -1468,14 +1474,13 @@
 	 * Clear accounting of old secondary address list,
 	 * don't count RAR[0]
 	 */
-	uc_addr_in_use = hw->addr_ctrl.rar_used_count -
-	    hw->addr_ctrl.mc_addr_in_rar_count - 1;
+	uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1;
 	hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
 	hw->addr_ctrl.overflow_promisc = 0;
 
 	/* Zero out the other receive addresses */
-	DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use);
-	for (i = 1; i <= uc_addr_in_use; i++) {
+	DEBUGOUT1("Clearing RAR[1-%d]\n", hw->addr_ctrl.rar_used_count);
+	for (i = 1; i <= hw->addr_ctrl.rar_used_count; i++) {
 		IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
 		IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
 	}
@@ -1587,25 +1592,6 @@
 }
 
 /*
- * ixgbe_add_mc_addr - Adds a multicast address.
- * @hw: pointer to hardware structure
- * @mc_addr: new multicast address
- *
- * Adds it to unused receive address register or to the multicast table.
- */
-void
-ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
-{
-	DEBUGOUT6(" MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n",
-	    mc_addr[0], mc_addr[1], mc_addr[2],
-	    mc_addr[3], mc_addr[4], mc_addr[5]);
-
-	ixgbe_set_mta(hw, mc_addr);
-
-	DEBUGOUT("ixgbe_add_mc_addr Complete\n");
-}
-
-/*
  * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
  * @hw: pointer to hardware structure
  * @mc_addr_list: the list of new multicast addresses
@@ -1639,7 +1625,7 @@
 	/* Add the new addresses */
 	for (i = 0; i < mc_addr_count; i++) {
 		DEBUGOUT(" Adding the multicast addresses:\n");
-		ixgbe_add_mc_addr(hw, next(hw, &mc_addr_list, &vmdq));
+		ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq));
 	}
 
 	/* Enable mta */
@@ -1660,15 +1646,8 @@
 s32
 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
 {
-	u32 i;
-	u32 rar_entries = hw->mac.num_rar_entries;
 	struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
 
-	if (a->mc_addr_in_rar_count > 0)
-		for (i = (rar_entries - a->mc_addr_in_rar_count);
-		    i < rar_entries; i++)
-			ixgbe_enable_rar(hw, i);
-
 	if (a->mta_in_use > 0)
 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
 		    hw->mac.mc_filter_type);
@@ -1685,15 +1664,8 @@
 s32
 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
 {
-	u32 i;
-	u32 rar_entries = hw->mac.num_rar_entries;
 	struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
 
-	if (a->mc_addr_in_rar_count > 0)
-		for (i = (rar_entries - a->mc_addr_in_rar_count);
-		    i < rar_entries; i++)
-			ixgbe_disable_rar(hw, i);
-
 	if (a->mta_in_use > 0)
 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
 
@@ -1701,6 +1673,319 @@
 }
 
 /*
+ * ixgbe_fc_enable_generic - Enable flow control
+ * @hw: pointer to hardware structure
+ * @packetbuf_num: packet buffer number (0-7)
+ *
+ * Enable flow control according to the current settings.
+ */
+s32
+ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+	s32 ret_val = IXGBE_SUCCESS;
+	u32 mflcn_reg, fccfg_reg;
+	u32 reg;
+
+	DEBUGFUNC("ixgbe_fc_enable_generic");
+
+	/* Negotiate the fc mode to use */
+	ret_val = ixgbe_fc_autoneg(hw);
+	if (ret_val)
+		goto out;
+
+	/* Disable any previous flow control settings */
+	mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+	mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
+
+	fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+	fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
+
+	/*
+	 * The possible values of fc.current_mode are:
+	 * 0: Flow control is completely disabled
+	 * 1: Rx flow control is enabled (we can receive pause frames,
+	 *    but not send pause frames).
+	 * 2: Tx flow control is enabled (we can send pause frames but
+	 *    we do not support receiving pause frames).
+	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
+	 * other: Invalid.
+	 */
+	switch (hw->fc.current_mode) {
+	case ixgbe_fc_none:
+		/*
+		 * Flow control is disabled by software override or autoneg.
+		 * The code below will actually disable it in the HW.
+		 */
+		break;
+	case ixgbe_fc_rx_pause:
+		/*
+		 * Rx Flow control is enabled and Tx Flow control is
+		 * disabled by software override. Since there really
+		 * isn't a way to advertise that we are capable of RX
+		 * Pause ONLY, we will advertise that we support both
+		 * symmetric and asymmetric Rx PAUSE.  Later, we will
+		 * disable the adapter's ability to send PAUSE frames.
+		 */
+		mflcn_reg |= IXGBE_MFLCN_RFCE;
+		break;
+	case ixgbe_fc_tx_pause:
+		/*
+		 * Tx Flow control is enabled, and Rx Flow control is
+		 * disabled by software override.
+		 */
+		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
+		break;
+	case ixgbe_fc_full:
+		/* Flow control (both Rx and Tx) is enabled by SW override. */
+		mflcn_reg |= IXGBE_MFLCN_RFCE;
+		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
+		break;
+	default:
+		DEBUGOUT("Flow control param set incorrectly\n");
+		ret_val = -IXGBE_ERR_CONFIG;
+		goto out;
+	}
+
+	/* Set 802.3x based flow control settings. */
+	mflcn_reg |= IXGBE_MFLCN_DPF;
+	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
+	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
+
+	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
+	if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
+		if (hw->fc.send_xon) {
+			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
+			    (hw->fc.low_water | IXGBE_FCRTL_XONE));
+		} else {
+			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
+			    hw->fc.low_water);
+		}
+
+		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
+		    (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+	}
+
+	/* Configure pause time (2 TCs per register) */
+	reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+	if ((packetbuf_num & 1) == 0)
+		reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
+	else
+		reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
+	IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+
+	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+
+out:
+	return (ret_val);
+}
+
+/*
+ * ixgbe_fc_autoneg - Configure flow control
+ * @hw: pointer to hardware structure
+ *
+ * Compares our advertised flow control capabilities to those advertised by
+ * our link partner, and determines the proper flow control mode to use.
+ */
+s32
+ixgbe_fc_autoneg(struct ixgbe_hw *hw)
+{
+	s32 ret_val = IXGBE_SUCCESS;
+	ixgbe_link_speed speed;
+	u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
+	bool link_up;
+
+	DEBUGFUNC("ixgbe_fc_autoneg");
+
+	/*
+	 * AN should have completed when the cable was plugged in.
+	 * Look for reasons to bail out.  Bail out if:
+	 * - FC autoneg is disabled, or if
+	 * - we don't have multispeed fiber, or if
+	 * - we're not running at 1G, or if
+	 * - link is not up, or if
+	 * - link is up but AN did not complete, or if
+	 * - link is up and AN completed but timed out
+	 *
+	 * Since we're being called from an LSC, link is already know to be up.
+	 * So use link_up_wait_to_complete=false.
+	 */
+	hw->mac.ops.check_link(hw, &speed, &link_up, false);
+	linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
+
+	if (hw->fc.disable_fc_autoneg ||
+	    !hw->phy.multispeed_fiber ||
+	    (speed != IXGBE_LINK_SPEED_1GB_FULL) ||
+	    !link_up ||
+	    ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
+	    ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
+		hw->fc.fc_was_autonegged = false;
+		hw->fc.current_mode = hw->fc.requested_mode;
+		DEBUGOUT("Autoneg FC was skipped.\n");
+		goto out;
+	}
+
+	/*
+	 * Read the AN advertisement and LP ability registers and resolve
+	 * local flow control settings accordingly
+	 */
+	pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+	pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
+	if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+	    (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
+		/*
+		 * Now we need to check if the user selected Rx ONLY
+		 * of pause frames.  In this case, we had to advertise
+		 * FULL flow control because we could not advertise RX
+		 * ONLY. Hence, we must now check to see if we need to
+		 * turn OFF the TRANSMISSION of PAUSE frames.
+		 */
+		if (hw->fc.requested_mode == ixgbe_fc_full) {
+			hw->fc.current_mode = ixgbe_fc_full;
+			DEBUGOUT("Flow Control = FULL.\n");
+		} else {
+			hw->fc.current_mode = ixgbe_fc_rx_pause;
+			DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
+		}
+	} else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+	    (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+	    (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+	    (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+		hw->fc.current_mode = ixgbe_fc_tx_pause;
+		DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
+	} else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+	    (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+	    !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+	    (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+		hw->fc.current_mode = ixgbe_fc_rx_pause;
+		DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
+	} else {
+		hw->fc.current_mode = ixgbe_fc_none;
+		DEBUGOUT("Flow Control = NONE.\n");
+	}
+
+	/* Record that current_mode is the result of a successful autoneg */
+	hw->fc.fc_was_autonegged = true;
+
+out:
+	return (ret_val);
+}
+
+/*
+ * ixgbe_setup_fc - Set up flow control
+ * @hw: pointer to hardware structure
+ *
+ * Called at init time to set up flow control.
+ */
+s32
+ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+	s32 ret_val = IXGBE_SUCCESS;
+	u32 reg;
+
+	/* Validate the packetbuf configuration */
+	if (packetbuf_num < 0 || packetbuf_num > 7) {
+		DEBUGOUT1("Invalid packet buffer number [%d], expected range is"
+		    " 0-7\n", packetbuf_num);
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * Validate the water mark configuration.  Zero water marks are invalid
+	 * because it causes the controller to just blast out fc packets.
+	 */
+	if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+		DEBUGOUT("Invalid water mark configuration\n");
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * Validate the requested mode.  Strict IEEE mode does not allow
+	 * ixgbe_fc_rx_pause because it will cause us to fail at UNH.
+	 */
+	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
+		DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * 10gig parts do not have a word in the EEPROM to determine the
+	 * default flow control setting, so we explicitly set it to full.
+	 */
+	if (hw->fc.requested_mode == ixgbe_fc_default)
+		hw->fc.requested_mode = ixgbe_fc_full;
+
+	/*
+	 * Set up the 1G flow control advertisement registers so the HW will be
+	 * able to do fc autoneg once the cable is plugged in.	If we end up
+	 * using 10g instead, this is harmless.
+	 */
+	reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+
+	/*
+	 * The possible values of fc.requested_mode are:
+	 * 0: Flow control is completely disabled
+	 * 1: Rx flow control is enabled (we can receive pause frames,
+	 *    but not send pause frames).
+	 * 2: Tx flow control is enabled (we can send pause frames but
+	 *    we do not support receiving pause frames).
+	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
+	 * other: Invalid.
+	 */
+	switch (hw->fc.requested_mode) {
+	case ixgbe_fc_none:
+		/* Flow control completely disabled by software override. */
+		reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+		break;
+	case ixgbe_fc_rx_pause:
+		/*
+		 * Rx Flow control is enabled and Tx Flow control is
+		 * disabled by software override. Since there really
+		 * isn't a way to advertise that we are capable of RX
+		 * Pause ONLY, we will advertise that we support both
+		 * symmetric and asymmetric Rx PAUSE.  Later, we will
+		 * disable the adapter's ability to send PAUSE frames.
+		 */
+		reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+		break;
+	case ixgbe_fc_tx_pause:
+		/*
+		 * Tx Flow control is enabled, and Rx Flow control is
+		 * disabled by software override.
+		 */
+		reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
+		reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
+		break;
+	case ixgbe_fc_full:
+		/* Flow control (both Rx and Tx) is enabled by SW override. */
+		reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+		break;
+	default:
+		DEBUGOUT("Flow control param set incorrectly\n");
+		ret_val = -IXGBE_ERR_CONFIG;
+		goto out;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
+	reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
+
+	/* Enable and restart autoneg to inform the link partner */
+	reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
+
+	/* Disable AN timeout */
+	if (hw->fc.strict_ieee)
+		reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
+	DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
+
+out:
+	return (ret_val);
+}
+
+/*
  * ixgbe_disable_pcie_master - Disable PCI-express master access
  * @hw: pointer to hardware structure
  *
@@ -1759,6 +2044,10 @@
 	s32 timeout = 200;
 
 	while (timeout) {
+		/*
+		 * SW EEPROM semaphore bit is used for access to all
+		 * SW_FW_SYNC/GSSR bits (not just EEPROM)
+		 */
 		if (ixgbe_get_eeprom_semaphore(hw))
 			return (-IXGBE_ERR_SWFW_SYNC);
 
@@ -1776,7 +2065,7 @@
 	}
 
 	if (!timeout) {
-		DEBUGOUT("Driver can't access resource, GSSR timeout.\n");
+		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
 		return (-IXGBE_ERR_SWFW_SYNC);
 	}
 
@@ -1809,3 +2098,75 @@
 
 	ixgbe_release_eeprom_semaphore(hw);
 }
+
+/*
+ * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
+ * @hw: pointer to hardware structure
+ * @regval: register value to write to RXCTRL
+ *
+ * Enables the Rx DMA unit
+ */
+s32
+ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
+{
+	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_blink_led_start_generic - Blink LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to blink
+ */
+s32
+ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
+{
+	ixgbe_link_speed speed = 0;
+	bool link_up = 0;
+	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+	/*
+	 * Link must be up to auto-blink the LEDs;
+	 * Force it if link is down.
+	 */
+	hw->mac.ops.check_link(hw, &speed, &link_up, false);
+
+	if (!link_up) {
+		autoc_reg |= IXGBE_AUTOC_FLU;
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+		msec_delay(10);
+	}
+
+	led_reg &= ~IXGBE_LED_MODE_MASK(index);
+	led_reg |= IXGBE_LED_BLINK(index);
+	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return (IXGBE_SUCCESS);
+}
+
+/*
+ * ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to stop blinking
+ */
+s32
+ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
+{
+	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+	autoc_reg &= ~IXGBE_AUTOC_FLU;
+	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+	led_reg &= ~IXGBE_LED_MODE_MASK(index);
+	led_reg &= ~IXGBE_LED_BLINK(index);
+	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
+	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return (IXGBE_SUCCESS);
+}
--- a/usr/src/uts/common/io/ixgbe/ixgbe_common.h	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_common.h	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,16 +23,15 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
-/* IntelVersion: 1.83 v2008-09-12 */
+/* IntelVersion: 1.90 v2-7-8_2009-4-7 */
 
 #ifndef _IXGBE_COMMON_H
 #define	_IXGBE_COMMON_H
 
 #include "ixgbe_type.h"
-#ident "$Id: ixgbe_common.h,v 1.83 2008/07/03 21:54:47 cwyborny Exp $"
 
 s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
 s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
@@ -41,6 +40,7 @@
 s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
 s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
 s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
+void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
 s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
 
 s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
@@ -64,8 +64,14 @@
     ixgbe_mc_addr_itr func);
 s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
     u32 addr_count, ixgbe_mc_addr_itr func);
+void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
 s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
+s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
+
+s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
+s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
 
 s32 ixgbe_validate_mac_addr(u8 *mac_addr);
 s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
@@ -74,5 +80,7 @@
 
 s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val);
 s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
+s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
 
 #endif /* _IXGBE_COMMON_H */
--- a/usr/src/uts/common/io/ixgbe/ixgbe_debug.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_debug.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
 #include "ixgbe_sw.h"
@@ -40,7 +40,7 @@
 {
 	ixgbe_t *ixgbe = (ixgbe_t *)adapter;
 	struct ixgbe_hw	*hw = &ixgbe->hw;
-	ixgbe_ring_vector_t	*vect;
+	ixgbe_intr_vector_t	*vect;
 	uint32_t		ivar, reg;
 	int i, j;
 
@@ -419,4 +419,73 @@
 
 	ddi_regs_map_free(&acc_hdl);
 }
+
+/*
+ * Dump registers
+ */
+void
+ixgbe_dump_regs(void *adapter)
+{
+	ixgbe_t *ixgbe = (ixgbe_t *)adapter;
+	uint32_t reg_val;
+	struct ixgbe_hw *hw = &ixgbe->hw;
+	int i;
+	DEBUGFUNC("ixgbe_dump_regs");
+
+	/* Dump basic's like CTRL, STATUS, CTRL_EXT. */
+	ixgbe_log(ixgbe, "Basic IXGBE registers..");
+	reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL);
+	ixgbe_log(ixgbe, "\tCTRL=%x\n", reg_val);
+	reg_val = IXGBE_READ_REG(hw, IXGBE_STATUS);
+	ixgbe_log(ixgbe, "\tSTATUS=%x\n", reg_val);
+	reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
+	ixgbe_log(ixgbe, "\tCTRL_EXT=%x\n", reg_val);
+	reg_val = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+	ixgbe_log(ixgbe, "\tFCTRL=%x\n", reg_val);
+
+	/* Misc Interrupt regs */
+	ixgbe_log(ixgbe, "Some IXGBE interrupt registers..");
+
+	reg_val = IXGBE_READ_REG(hw, IXGBE_GPIE);
+	ixgbe_log(ixgbe, "\tGPIE=%x\n", reg_val);
+
+	reg_val = IXGBE_READ_REG(hw, IXGBE_IVAR(0));
+	ixgbe_log(ixgbe, "\tIVAR(0)=%x\n", reg_val);
+
+	reg_val = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC);
+	ixgbe_log(ixgbe, "\tIVAR_MISC=%x\n", reg_val);
+
+	/* Dump RX related reg's */
+	ixgbe_log(ixgbe, "Receive registers...");
+	reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+	ixgbe_log(ixgbe, "\tRXCTRL=%x\n", reg_val);
+	for (i = 0; i < ixgbe->num_rx_rings; i++) {
+		reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+		ixgbe_log(ixgbe, "\tRXDCTL(%d)=%x\n", i, reg_val);
+		reg_val = IXGBE_READ_REG(hw, IXGBE_SRRCTL(i));
+		ixgbe_log(ixgbe, "\tSRRCTL(%d)=%x\n", i, reg_val);
+	}
+	reg_val = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
+	ixgbe_log(ixgbe, "\tRXCSUM=%x\n", reg_val);
+	reg_val = IXGBE_READ_REG(hw, IXGBE_MRQC);
+	ixgbe_log(ixgbe, "\tMRQC=%x\n", reg_val);
+	reg_val = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+	ixgbe_log(ixgbe, "\tRDRXCTL=%x\n", reg_val);
+
+	/* Dump TX related regs */
+	ixgbe_log(ixgbe, "Some transmit registers..");
+	reg_val = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+	ixgbe_log(ixgbe, "\tDMATXCTL=%x\n", reg_val);
+	for (i = 0; i < ixgbe->num_tx_rings; i++) {
+		reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
+		ixgbe_log(ixgbe, "\tTXDCTL(%d)=%x\n", i, reg_val);
+		reg_val = IXGBE_READ_REG(hw, IXGBE_TDWBAL(i));
+		ixgbe_log(ixgbe, "\tTDWBAL(%d)=%x\n", i, reg_val);
+		reg_val = IXGBE_READ_REG(hw, IXGBE_TDWBAH(i));
+		ixgbe_log(ixgbe, "\tTDWBAH(%d)=%x\n", i, reg_val);
+		reg_val = IXGBE_READ_REG(hw, IXGBE_TXPBSIZE(i));
+		ixgbe_log(ixgbe, "\tTXPBSIZE(%d)=%x\n", i, reg_val);
+	}
+}
+
 #endif
--- a/usr/src/uts/common/io/ixgbe/ixgbe_debug.h	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_debug.h	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -22,15 +22,13 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #ifndef	_IXGBE_DEBUG_H
 #define	_IXGBE_DEBUG_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -79,6 +77,34 @@
 
 #endif	/* IXGBE_DEBUG */
 
+#ifdef IXGBE_DEBUG
+
+#define	DEBUGOUT(S)	\
+	IXGBE_DEBUGLOG_0(NULL, S)
+#define	DEBUGOUT1(S, A)	\
+	IXGBE_DEBUGLOG_1(NULL, S, A)
+#define	DEBUGOUT2(S, A, B)	\
+	IXGBE_DEBUGLOG_2(NULL, S, A, B)
+#define	DEBUGOUT3(S, A, B, C)	\
+	IXGBE_DEBUGLOG_3(NULL, S, A, B, C)
+#define	DEBUGOUT6(S, A, B, C, D, E, F)	\
+	IXGBE_DEBUGLOG_6(NULL, S, A, B, C, D, E, F)
+
+#define	DEBUGFUNC(F)	\
+	IXGBE_DEBUGLOG_0(NULL, F)
+
+#else
+
+#define	DEBUGOUT(S)
+#define	DEBUGOUT1(S, A)
+#define	DEBUGOUT2(S, A, B)
+#define	DEBUGOUT3(S, A, B, C)
+#define	DEBUGOUT6(S, A, B, C, D, E, F)
+
+#define	DEBUGFUNC(F)
+
+#endif	/* IXGBE_DEBUG */
+
 extern void ixgbe_log(void *, const char *, ...);
 
 #ifdef __cplusplus
--- a/usr/src/uts/common/io/ixgbe/ixgbe_gld.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_gld.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,6 +1,7 @@
 /*
  * CDDL HEADER START
  *
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -20,11 +21,7 @@
  */
 
 /*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -116,8 +113,15 @@
 	case MAC_STAT_OBYTES:
 		ixgbe_ks->tot.value.ui64 = 0;
 		for (i = 0; i < 16; i++) {
-			ixgbe_ks->qbtc[i].value.ui64 +=
-			    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+			if (hw->mac.type >= ixgbe_mac_82599EB) {
+				ixgbe_ks->qbtc[i].value.ui64 +=
+				    IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
+				ixgbe_ks->qbtc[i].value.ui64 += ((uint64_t)
+				    IXGBE_READ_REG(hw, IXGBE_QBTC_H(i))) << 32;
+			} else {
+				ixgbe_ks->qbtc[i].value.ui64 +=
+				    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+			}
 			ixgbe_ks->tot.value.ui64 +=
 			    ixgbe_ks->qbtc[i].value.ui64;
 		}
--- a/usr/src/uts/common/io/ixgbe/ixgbe_main.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_main.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,6 +1,7 @@
 /*
  * CDDL HEADER START
  *
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -20,15 +21,10 @@
  */
 
 /*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-
 #include "ixgbe_sw.h"
 
 static char ident[] = "Intel 10Gb Ethernet";
@@ -68,6 +64,7 @@
 static void ixgbe_get_conf(ixgbe_t *);
 static int ixgbe_get_prop(ixgbe_t *, char *, int, int, int);
 static void ixgbe_driver_link_check(void *);
+static void ixgbe_sfp_check(void *);
 static void ixgbe_local_timer(void *);
 static void ixgbe_arm_watchdog_timer(ixgbe_t *);
 static void ixgbe_restart_watchdog_timer(ixgbe_t *);
@@ -83,10 +80,10 @@
 static int ixgbe_add_intr_handlers(ixgbe_t *);
 static void ixgbe_map_rxring_to_vector(ixgbe_t *, int, int);
 static void ixgbe_map_txring_to_vector(ixgbe_t *, int, int);
-static void ixgbe_setup_ivar(ixgbe_t *, uint16_t, uint8_t);
-static void ixgbe_enable_ivar(ixgbe_t *, uint16_t);
-static void ixgbe_disable_ivar(ixgbe_t *, uint16_t);
-static int ixgbe_map_rings_to_vectors(ixgbe_t *);
+static void ixgbe_setup_ivar(ixgbe_t *, uint16_t, uint8_t, int8_t);
+static void ixgbe_enable_ivar(ixgbe_t *, uint16_t, int8_t);
+static void ixgbe_disable_ivar(ixgbe_t *, uint16_t, int8_t);
+static int ixgbe_map_intrs_to_vectors(ixgbe_t *);
 static void ixgbe_setup_adapter_vector(ixgbe_t *);
 static void ixgbe_rem_intr_handlers(ixgbe_t *);
 static void ixgbe_rem_intrs(ixgbe_t *);
@@ -94,8 +91,7 @@
 static int ixgbe_disable_intrs(ixgbe_t *);
 static uint_t ixgbe_intr_legacy(void *, void *);
 static uint_t ixgbe_intr_msi(void *, void *);
-static uint_t ixgbe_intr_rx_tx(void *, void *);
-static uint_t ixgbe_intr_other(void *, void *);
+static uint_t ixgbe_intr_msix(void *, void *);
 static void ixgbe_intr_rx_work(ixgbe_rx_ring_t *);
 static void ixgbe_intr_tx_work(ixgbe_tx_ring_t *);
 static void ixgbe_intr_other_work(ixgbe_t *, uint32_t);
@@ -217,6 +213,22 @@
 	| IXGBE_FLAG_VMDQ_CAPABLE)
 };
 
+static adapter_info_t ixgbe_82599eb_cap = {
+	128,		/* maximum number of rx queues */
+	1,		/* minimum number of rx queues */
+	8,		/* default number of rx queues */
+	128,		/* maximum number of tx queues */
+	1,		/* minimum number of tx queues */
+	8,		/* default number of tx queues */
+	64,		/* maximum total msix vectors */
+	16,		/* maximum number of ring vectors */
+	2,		/* maximum number of other vectors */
+	IXGBE_EICR_LSC,	/* "other" interrupt types handled */
+	(IXGBE_FLAG_DCA_CAPABLE	/* capability flags */
+	| IXGBE_FLAG_RSS_CAPABLE
+	| IXGBE_FLAG_VMDQ_CAPABLE)
+};
+
 /*
  * Module Initialization Functions.
  */
@@ -381,8 +393,8 @@
 	/*
 	 * Map rings to interrupt vectors
 	 */
-	if (ixgbe_map_rings_to_vectors(ixgbe) != IXGBE_SUCCESS) {
-		ixgbe_error(ixgbe, "Failed to map rings to vectors");
+	if (ixgbe_map_intrs_to_vectors(ixgbe) != IXGBE_SUCCESS) {
+		ixgbe_error(ixgbe, "Failed to map interrupts to vectors");
 		goto attach_fail;
 	}
 
@@ -761,13 +773,22 @@
 	 */
 	switch (hw->mac.type) {
 	case ixgbe_mac_82598EB:
-		ixgbe_log(ixgbe, "identify oplin adapter\n");
+		ixgbe_log(ixgbe, "identify 82598 adapter\n");
 		ixgbe->capab = &ixgbe_82598eb_cap;
 
 		if (ixgbe_get_media_type(hw) == ixgbe_media_type_copper) {
 			ixgbe->capab->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
 			ixgbe->capab->other_intr |= IXGBE_EICR_GPI_SDP1;
 		}
+		ixgbe->capab->other_intr |= IXGBE_EICR_LSC;
+
+		break;
+	case ixgbe_mac_82599EB:
+		ixgbe_log(ixgbe, "identify 82599 adapter\n");
+		ixgbe->capab = &ixgbe_82599eb_cap;
+
+		ixgbe->capab->other_intr = (IXGBE_EICR_GPI_SDP1 |
+		    IXGBE_EICR_GPI_SDP2 | IXGBE_EICR_LSC);
 
 		break;
 	default:
@@ -795,14 +816,15 @@
 	/*
 	 * First get the size of device registers to be mapped.
 	 */
-	if (ddi_dev_regsize(devinfo, 1, &mem_size) != DDI_SUCCESS) {
+	if (ddi_dev_regsize(devinfo, IXGBE_ADAPTER_REGSET, &mem_size)
+	    != DDI_SUCCESS) {
 		return (IXGBE_FAILURE);
 	}
 
 	/*
 	 * Call ddi_regs_map_setup() to map registers
 	 */
-	if ((ddi_regs_map_setup(devinfo, 1,
+	if ((ddi_regs_map_setup(devinfo, IXGBE_ADAPTER_REGSET,
 	    (caddr_t *)&hw->hw_addr, 0,
 	    mem_size, &ixgbe_regs_acc_attr,
 	    &osdep->reg_handle)) != DDI_SUCCESS) {
@@ -908,13 +930,14 @@
 	/*
 	 * Initialize values of interrupt throttling rate
 	 */
-	for (i = 1; i < MAX_RING_VECTOR; i++)
+	for (i = 1; i < MAX_INTR_VECTOR; i++)
 		ixgbe->intr_throttling[i] = ixgbe->intr_throttling[0];
 
 	/*
 	 * The initial link state should be "unknown"
 	 */
 	ixgbe->link_state = LINK_STATE_UNKNOWN;
+
 	return (IXGBE_SUCCESS);
 }
 
@@ -1237,8 +1260,9 @@
 	/*
 	 * Set interrupt throttling rate
 	 */
-	for (i = 0; i < ixgbe->intr_cnt; i++)
+	for (i = 0; i < ixgbe->intr_cnt; i++) {
 		IXGBE_WRITE_REG(hw, IXGBE_EITR(i), ixgbe->intr_throttling[i]);
+	}
 
 	/*
 	 * Save the state of the phy
@@ -1774,16 +1798,26 @@
 	 */
 	reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->index));
 	reg_val |= IXGBE_RXDCTL_ENABLE;	/* enable queue */
-	reg_val |= 0x0020;		/* pthresh */
+
+	/* Not a valid value for 82599 */
+	if (hw->mac.type < ixgbe_mac_82599EB) {
+		reg_val |= 0x0020;	/* pthresh */
+	}
 	IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->index), reg_val);
 
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		reg_val = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+		reg_val |= (IXGBE_RDRXCTL_CRCSTRIP | IXGBE_RDRXCTL_AGGDIS);
+		IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg_val);
+	}
+
 	/*
 	 * Setup the Split and Replication Receive Control Register.
 	 * Set the rx buffer size and the advanced descriptor type.
 	 */
 	reg_val = (ixgbe->rx_buf_size >> IXGBE_SRRCTL_BSIZEPKT_SHIFT) |
 	    IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
-
+	reg_val |= IXGBE_SRRCTL_DROP_EN;
 	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rx_ring->index), reg_val);
 }
 
@@ -1797,6 +1831,14 @@
 	uint32_t ring_mapping;
 	int i;
 
+	/* PSRTYPE must be configured for 82599 */
+	reg_val = IXGBE_PSRTYPE_TCPHDR | IXGBE_PSRTYPE_UDPHDR |
+	    IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_IPV6HDR;
+#define	IXGBE_PSRTYPE_L2_PKT	0x00001000
+	reg_val |= IXGBE_PSRTYPE_L2_PKT;
+	reg_val |= 0xE0000000;
+	IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), reg_val);
+
 	/*
 	 * Set filter control in FCTRL to accept broadcast packets and do
 	 * not pass pause frames to host.  Flow control settings are already
@@ -1847,9 +1889,10 @@
 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i >> 2), ring_mapping);
 
 	/*
-	 * The Max Frame Size in MHADD will be internally increased by four
-	 * bytes if the packet has a VLAN field, so includes MTU, ethernet
-	 * header and frame check sequence.
+	 * The Max Frame Size in MHADD/MAXFRS will be internally increased
+	 * by four bytes if the packet has a VLAN field, so includes MTU,
+	 * ethernet header and frame check sequence.
+	 * Register is MAXFRS in 82599.
 	 */
 	reg_val = (ixgbe->default_mtu + sizeof (struct ether_header)
 	    + ETHERFCSL) << IXGBE_MHADD_MFS_SHIFT;
@@ -1907,12 +1950,6 @@
 	IXGBE_WRITE_REG(hw, IXGBE_TDBAH(tx_ring->index), buf_high);
 
 	/*
-	 * setup TXDCTL(tx_ring->index)
-	 */
-	reg_val = IXGBE_TXDCTL_ENABLE;
-	IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->index), reg_val);
-
-	/*
 	 * Setup head & tail pointers
 	 */
 	IXGBE_WRITE_REG(hw, IXGBE_TDH(tx_ring->index), 0);
@@ -1997,12 +2034,22 @@
 	for (i = 0; i < ixgbe->num_tx_rings; i++) {
 		ring_mapping |= (i & 0xF) << (8 * (i & 0x3));
 		if ((i & 0x3) == 0x3) {
-			IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i >> 2), ring_mapping);
+			if (hw->mac.type >= ixgbe_mac_82599EB) {
+				IXGBE_WRITE_REG(hw, IXGBE_TQSM(i >> 2),
+				    ring_mapping);
+			} else {
+				IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i >> 2),
+				    ring_mapping);
+			}
 			ring_mapping = 0;
 		}
 	}
 	if ((i & 0x3) != 0x3)
-		IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i >> 2), ring_mapping);
+		if (hw->mac.type >= ixgbe_mac_82599EB) {
+			IXGBE_WRITE_REG(hw, IXGBE_TQSM(i >> 2), ring_mapping);
+		} else {
+			IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i >> 2), ring_mapping);
+		}
 
 	/*
 	 * Enable CRC appending and TX padding (for short tx frames)
@@ -2010,6 +2057,27 @@
 	reg_val = IXGBE_READ_REG(hw, IXGBE_HLREG0);
 	reg_val |= IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_TXPADEN;
 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg_val);
+
+	/*
+	 * enable DMA for 82599 parts
+	 */
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+	/* DMATXCTL.TE must be set after all Tx config is complete */
+		reg_val = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+		reg_val |= IXGBE_DMATXCTL_TE;
+		IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_val);
+	}
+
+	/*
+	 * Enabling tx queues ..
+	 * For 82599 must be done after DMATXCTL.TE is set
+	 */
+	for (i = 0; i < ixgbe->num_tx_rings; i++) {
+		tx_ring = &ixgbe->tx_rings[i];
+		reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->index));
+		reg_val |= IXGBE_TXDCTL_ENABLE;
+		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->index), reg_val);
+	}
 }
 
 /*
@@ -2315,7 +2383,11 @@
 	if (flow_control == 3)
 		flow_control = ixgbe_fc_default;
 
-	hw->fc.type = flow_control;
+	/*
+	 * fc.requested mode is what the user requests.  After autoneg,
+	 * fc.current_mode will be the flow_control mode that was negotiated.
+	 */
+	hw->fc.requested_mode = flow_control;
 
 	/*
 	 * Multiple rings configurations
@@ -2369,6 +2441,11 @@
 	ixgbe->tx_head_wb_enable = ixgbe_get_prop(ixgbe, PROP_TX_HEAD_WB_ENABLE,
 	    0, 1, DEFAULT_TX_HEAD_WB_ENABLE);
 
+	/* Head Write Back not recommended for 82599 */
+	if (hw->mac.type >= ixgbe_mac_82599EB) {
+		ixgbe->tx_head_wb_enable = B_FALSE;
+	}
+
 	/*
 	 * ixgbe LSO needs the tx h/w checksum support.
 	 * LSO will be disabled if tx h/w checksum is not
@@ -2398,9 +2475,24 @@
 	    MIN_RX_LIMIT_PER_INTR, MAX_RX_LIMIT_PER_INTR,
 	    DEFAULT_RX_LIMIT_PER_INTR);
 
-	ixgbe->intr_throttling[0] = ixgbe_get_prop(ixgbe, PROP_INTR_THROTTLING,
-	    MIN_INTR_THROTTLING, MAX_INTR_THROTTLING,
-	    DEFAULT_INTR_THROTTLING);
+	/*
+	 * Interrupt throttling is per 256ns in 82598 and 2 usec increments
+	 * in 82599.
+	 */
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		ixgbe->intr_throttling[0] = ixgbe_get_prop(ixgbe,
+		    PROP_INTR_THROTTLING,
+		    MIN_INTR_THROTTLING, MAX_INTR_THROTTLING_82598,
+		    DEFAULT_INTR_THROTTLING_82598);
+		break;
+	case ixgbe_mac_82599EB:
+		ixgbe->intr_throttling[0] = ixgbe_get_prop(ixgbe,
+		    PROP_INTR_THROTTLING,
+		    MIN_INTR_THROTTLING, MAX_INTR_THROTTLING_82599,
+		    DEFAULT_INTR_THROTTLING_82599);
+		break;
+	}
 }
 
 /*
@@ -2479,8 +2571,11 @@
 	}
 
 	if (setup_hw) {
-		if (ixgbe_setup_link(&ixgbe->hw) != IXGBE_SUCCESS)
+		if (ixgbe_setup_link(&ixgbe->hw) != IXGBE_SUCCESS) {
+			ixgbe_notice(ixgbe, "Setup link failed on this "
+			    "device.");
 			return (IXGBE_FAILURE);
+		}
 	}
 
 	return (IXGBE_SUCCESS);
@@ -2503,19 +2598,22 @@
 	/* check for link, wait the full time */
 	(void) ixgbe_check_link(hw, &speed, &link_up, true);
 	if (link_up) {
+		/* Link is up, enable flow control settings */
+		(void) ixgbe_fc_enable(hw, 0);
+
 		/*
 		 * The Link is up, check whether it was marked as down earlier
 		 */
 		if (ixgbe->link_state != LINK_STATE_UP) {
 			switch (speed) {
-				case IXGBE_LINK_SPEED_10GB_FULL:
-					ixgbe->link_speed = SPEED_10GB;
-					break;
-				case IXGBE_LINK_SPEED_1GB_FULL:
-					ixgbe->link_speed = SPEED_1GB;
-					break;
-				case IXGBE_LINK_SPEED_100_FULL:
-					ixgbe->link_speed = SPEED_100;
+			case IXGBE_LINK_SPEED_10GB_FULL:
+				ixgbe->link_speed = SPEED_10GB;
+				break;
+			case IXGBE_LINK_SPEED_1GB_FULL:
+				ixgbe->link_speed = SPEED_1GB;
+				break;
+			case IXGBE_LINK_SPEED_100_FULL:
+				ixgbe->link_speed = SPEED_100;
 			}
 			ixgbe->link_duplex = LINK_DUPLEX_FULL;
 			ixgbe->link_state = LINK_STATE_UP;
@@ -2560,6 +2658,41 @@
 }
 
 /*
+ * ixgbe_sfp_check - sfp module processing done in taskq only for 82599.
+ */
+static void
+ixgbe_sfp_check(void *arg)
+{
+	ixgbe_t *ixgbe = (ixgbe_t *)arg;
+	uint32_t eicr = ixgbe->eicr;
+	struct ixgbe_hw *hw = &ixgbe->hw;
+	uint32_t autoneg;
+
+	if (eicr & IXGBE_EICR_GPI_SDP1) {
+		/* clear the interrupt */
+		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
+
+		/* if link up, do multispeed fiber setup */
+		(void) ixgbe_get_link_capabilities(hw, &autoneg,
+		    &hw->mac.autoneg);
+		(void) ixgbe_setup_link_speed(hw, autoneg, B_TRUE, B_TRUE);
+		ixgbe_driver_link_check(ixgbe);
+	} else if (eicr & IXGBE_EICR_GPI_SDP2) {
+		/* clear the interrupt */
+		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
+
+		/* if link up, do sfp module setup */
+		(void) hw->mac.ops.setup_sfp(hw);
+
+		/* do multispeed fiber setup */
+		(void) ixgbe_get_link_capabilities(hw, &autoneg,
+		    &hw->mac.autoneg);
+		(void) ixgbe_setup_link_speed(hw, autoneg, B_TRUE, B_TRUE);
+		ixgbe_driver_link_check(ixgbe);
+	}
+}
+
+/*
  * ixgbe_local_timer - Driver watchdog function.
  *
  * This function will handle the transmit stall check, link status check and
@@ -2571,6 +2704,7 @@
 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
 
 	if (ixgbe_stall_check(ixgbe)) {
+		ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_DEGRADED);
 		ixgbe->reset_count++;
 		if (ixgbe_reset(ixgbe) == IXGBE_SUCCESS)
 			ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_RESTORED);
@@ -2883,8 +3017,20 @@
 		/* disable autoclear, leave gpie at default */
 		eiac = 0;
 
-		/* general purpose interrupt enable */
-		gpie |= IXGBE_GPIE_EIAME;
+		/*
+		 * General purpose interrupt enable.
+		 * For 82599, extended interrupt automask enable
+		 * only in MSI or MSI-X mode
+		 */
+		if ((hw->mac.type < ixgbe_mac_82599EB) ||
+		    (ixgbe->intr_type == DDI_INTR_TYPE_MSI)) {
+			gpie |= IXGBE_GPIE_EIAME;
+		}
+	}
+	/* Enable specific interrupts for 82599  */
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		gpie |= IXGBE_SDP2_GPIEN; /* pluggable optics intr */
+		gpie |= IXGBE_SDP1_GPIEN; /* LSC interrupt */
 	}
 
 	/* write to interrupt control registers */
@@ -3117,6 +3263,7 @@
 static void
 ixgbe_intr_other_work(ixgbe_t *ixgbe, uint32_t eicr)
 {
+	struct ixgbe_hw *hw = &ixgbe->hw;
 	/*
 	 * dispatch taskq to handle link status change
 	 */
@@ -3133,12 +3280,25 @@
 	 */
 	if ((ixgbe->capab->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) &&
 	    (eicr & IXGBE_EICR_GPI_SDP1)) {
-
-		ixgbe_log(ixgbe,
-		    "Fan has stopped, replace the adapter\n");
-
-		/* re-enable the interrupt, which was automasked */
-		ixgbe->eims |= IXGBE_EICR_GPI_SDP1;
+		if (hw->mac.type < ixgbe_mac_82599EB) {
+			ixgbe_log(ixgbe,
+			    "Fan has stopped, replace the adapter\n");
+
+			/* re-enable the interrupt, which was automasked */
+			ixgbe->eims |= IXGBE_EICR_GPI_SDP1;
+		}
+	}
+
+	/*
+	 * Do SFP check for 82599
+	 */
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		if ((ddi_taskq_dispatch(ixgbe->lsc_taskq,
+		    ixgbe_sfp_check, (void *)ixgbe,
+		    DDI_NOSLEEP)) != DDI_SUCCESS) {
+			ixgbe_log(ixgbe,
+			    "No memory available to dispatch taskq");
+		}
 	}
 }
 
@@ -3185,6 +3345,9 @@
 		 * For legacy interrupt, rx rings[0] will use RTxQ[0].
 		 */
 		if (eicr & 0x1) {
+			ixgbe->eimc |= IXGBE_EICR_RTX_QUEUE;
+			IXGBE_WRITE_REG(hw, IXGBE_EIMC, ixgbe->eimc);
+			ixgbe->eims |= IXGBE_EICR_RTX_QUEUE;
 			/*
 			 * Clean the rx descriptors
 			 */
@@ -3211,8 +3374,15 @@
 
 		/* any interrupt type other than tx/rx */
 		if (eicr & ixgbe->capab->other_intr) {
+			if (hw->mac.type < ixgbe_mac_82599EB) {
+				ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR);
+			}
+			if (hw->mac.type == ixgbe_mac_82599EB) {
+				ixgbe->eimc = IXGBE_82599_OTHER_INTR;
+				IXGBE_WRITE_REG(hw, IXGBE_EIMC, ixgbe->eimc);
+			}
+			ixgbe_intr_other_work(ixgbe, eicr);
 			ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR);
-			ixgbe_intr_other_work(ixgbe, eicr);
 		}
 
 		mutex_exit(&ixgbe->gen_lock);
@@ -3233,9 +3403,10 @@
 	/*
 	 * Do the following work outside of the gen_lock
 	 */
-	if (mp != NULL)
+	if (mp != NULL) {
 		mac_rx_ring(rx_ring->ixgbe->mac_hdl, rx_ring->ring_handle, mp,
 		    rx_ring->ring_gen_num);
+	}
 
 	if (tx_reschedule)  {
 		tx_ring->reschedule = B_FALSE;
@@ -3284,8 +3455,15 @@
 	/* any interrupt type other than tx/rx */
 	if (eicr & ixgbe->capab->other_intr) {
 		mutex_enter(&ixgbe->gen_lock);
+		if (hw->mac.type < ixgbe_mac_82599EB) {
+			ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR);
+		}
+		if (hw->mac.type == ixgbe_mac_82599EB) {
+			ixgbe->eimc = IXGBE_82599_OTHER_INTR;
+			IXGBE_WRITE_REG(hw, IXGBE_EIMC, ixgbe->eimc);
+		}
+		ixgbe_intr_other_work(ixgbe, eicr);
 		ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR);
-		ixgbe_intr_other_work(ixgbe, eicr);
 		mutex_exit(&ixgbe->gen_lock);
 	}
 
@@ -3296,13 +3474,15 @@
 }
 
 /*
- * ixgbe_intr_rx_tx - Interrupt handler for rx and tx.
+ * ixgbe_intr_msix - Interrupt handler for MSI-X.
  */
 static uint_t
-ixgbe_intr_rx_tx(void *arg1, void *arg2)
+ixgbe_intr_msix(void *arg1, void *arg2)
 {
-	ixgbe_ring_vector_t *vect = (ixgbe_ring_vector_t *)arg1;
+	ixgbe_intr_vector_t *vect = (ixgbe_intr_vector_t *)arg1;
 	ixgbe_t *ixgbe = vect->ixgbe;
+	struct ixgbe_hw *hw = &ixgbe->hw;
+	uint32_t eicr;
 	int r_idx = 0;
 
 	_NOTE(ARGUNUSED(arg2));
@@ -3327,41 +3507,38 @@
 		    (ixgbe->num_tx_rings - 1));
 	}
 
-	return (DDI_INTR_CLAIMED);
-}
-
-/*
- * ixgbe_intr_other - Interrupt handler for other.
- *
- * Only look for other work if the right bits are set in the
- * Interrupt Cause Register.
- */
-static uint_t
-ixgbe_intr_other(void *arg1, void *arg2)
-{
-	ixgbe_t *ixgbe = (ixgbe_t *)arg1;
-	struct ixgbe_hw *hw = &ixgbe->hw;
-	uint32_t eicr;
-
-	_NOTE(ARGUNUSED(arg2));
-
-	eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
 
 	/*
-	 * Need check cause bits and only other causes will
-	 * be processed
+	 * Clean other interrupt (link change) that has its bit set in the map
 	 */
-	/* any interrupt type other than tx/rx */
-	if (eicr & ixgbe->capab->other_intr) {
-		mutex_enter(&ixgbe->gen_lock);
-		ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR);
-		ixgbe_intr_other_work(ixgbe, eicr);
-		mutex_exit(&ixgbe->gen_lock);
+	if (BT_TEST(vect->other_map, 0) == 1) {
+		eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
+
+		/*
+		 * Need check cause bits and only other causes will
+		 * be processed
+		 */
+		/* any interrupt type other than tx/rx */
+		if (eicr & ixgbe->capab->other_intr) {
+			if (hw->mac.type < ixgbe_mac_82599EB) {
+				mutex_enter(&ixgbe->gen_lock);
+				ixgbe->eims &= ~(eicr & IXGBE_OTHER_INTR);
+				ixgbe_intr_other_work(ixgbe, eicr);
+				mutex_exit(&ixgbe->gen_lock);
+			} else {
+				if (hw->mac.type == ixgbe_mac_82599EB) {
+					mutex_enter(&ixgbe->gen_lock);
+					ixgbe->eims |= IXGBE_EICR_RTX_QUEUE;
+					ixgbe_intr_other_work(ixgbe, eicr);
+					mutex_exit(&ixgbe->gen_lock);
+				}
+			}
+		}
+
+		/* re-enable the interrupts which were automasked */
+		IXGBE_WRITE_REG(hw, IXGBE_EIMS, ixgbe->eims);
 	}
 
-	/* re-enable the interrupts which were automasked */
-	IXGBE_WRITE_REG(hw, IXGBE_EIMS, ixgbe->eims);
-
 	return (DDI_INTR_CLAIMED);
 }
 
@@ -3484,11 +3661,11 @@
 	case DDI_INTR_TYPE_MSIX:
 		/*
 		 * Best number of vectors for the adapter is
-		 * # rx rings + # tx rings + 1 for other.
+		 * # rx rings + # tx rings.
 		 */
-		request = ixgbe->num_rx_rings + ixgbe->num_tx_rings + 1;
-		if (request > (ixgbe->capab->max_ring_vect + 1))
-			request = ixgbe->capab->max_ring_vect + 1;
+		request = ixgbe->num_rx_rings + ixgbe->num_tx_rings;
+		if (request > ixgbe->capab->max_ring_vect)
+			request = ixgbe->capab->max_ring_vect;
 		minimum = 2;
 		IXGBE_DEBUGLOG_0(ixgbe, "interrupt type: MSI-X");
 		break;
@@ -3605,15 +3782,14 @@
 	switch (ixgbe->intr_type) {
 	case DDI_INTR_TYPE_MSIX:
 		/*
-		 * Add interrupt handler for rx and tx rings: vector[0 -
-		 * (ixgbe->intr_cnt -1)].
+		 * Add interrupt handler for all vectors
 		 */
-		for (vector = 0; vector < (ixgbe->intr_cnt -1); vector++) {
+		for (vector = 0; vector < ixgbe->intr_cnt; vector++) {
 			/*
 			 * install pointer to vect_map[vector]
 			 */
 			rc = ddi_intr_add_handler(ixgbe->htable[vector],
-			    (ddi_intr_handler_t *)ixgbe_intr_rx_tx,
+			    (ddi_intr_handler_t *)ixgbe_intr_msix,
 			    (void *)&ixgbe->vect_map[vector], NULL);
 
 			if (rc != DDI_SUCCESS) {
@@ -3628,18 +3804,6 @@
 			}
 		}
 
-		/*
-		 * Add interrupt handler for other: vector[ixgbe->intr_cnt -1]
-		 */
-		rc = ddi_intr_add_handler(ixgbe->htable[vector],
-		    (ddi_intr_handler_t *)ixgbe_intr_other,
-		    (void *)ixgbe, NULL);
-		if (rc != DDI_SUCCESS) {
-			ixgbe_log(ixgbe,
-			    "Add other interrupt handler failed: %d", rc);
-			return (IXGBE_FAILURE);
-		}
-
 		break;
 
 	case DDI_INTR_TYPE_MSI:
@@ -3678,8 +3842,6 @@
 		return (IXGBE_FAILURE);
 	}
 
-	ASSERT(vector == (ixgbe->intr_cnt -1));
-
 	return (IXGBE_SUCCESS);
 }
 
@@ -3690,8 +3852,6 @@
 static void
 ixgbe_map_rxring_to_vector(ixgbe_t *ixgbe, int r_idx, int v_idx)
 {
-	ixgbe->vect_map[v_idx].ixgbe = ixgbe;
-
 	/*
 	 * Set bit in map
 	 */
@@ -3716,8 +3876,6 @@
 static void
 ixgbe_map_txring_to_vector(ixgbe_t *ixgbe, int t_idx, int v_idx)
 {
-	ixgbe->vect_map[v_idx].ixgbe = ixgbe;
-
 	/*
 	 * Set bit in map
 	 */
@@ -3738,66 +3896,166 @@
 /*
  * ixgbe_setup_ivar - Set the given entry in the given interrupt vector
  * allocation register (IVAR).
+ * cause:
+ *   -1 : other cause
+ *    0 : rx
+ *    1 : tx
  */
 static void
-ixgbe_setup_ivar(ixgbe_t *ixgbe, uint16_t intr_alloc_entry, uint8_t msix_vector)
+ixgbe_setup_ivar(ixgbe_t *ixgbe, uint16_t intr_alloc_entry, uint8_t msix_vector,
+    int8_t cause)
 {
 	struct ixgbe_hw *hw = &ixgbe->hw;
 	u32 ivar, index;
 
-	msix_vector |= IXGBE_IVAR_ALLOC_VAL;
-	index = (intr_alloc_entry >> 2) & 0x1F;
-	ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
-	ivar &= ~(0xFF << (8 * (intr_alloc_entry & 0x3)));
-	ivar |= (msix_vector << (8 * (intr_alloc_entry & 0x3)));
-	IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+		if (cause == -1) {
+			cause = 0;
+		}
+		index = (((cause * 64) + intr_alloc_entry) >> 2) & 0x1F;
+		ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
+		ivar &= ~(0xFF << (8 * (intr_alloc_entry & 0x3)));
+		ivar |= (msix_vector << (8 * (intr_alloc_entry & 0x3)));
+		IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+		break;
+	case ixgbe_mac_82599EB:
+		if (cause == -1) {
+			/* other causes */
+			msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+			index = (intr_alloc_entry & 1) * 8;
+			ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC);
+			ivar &= ~(0xFF << index);
+			ivar |= (msix_vector << index);
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, ivar);
+		} else {
+			/* tx or rx causes */
+			msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+			index = ((16 * (intr_alloc_entry & 1)) + (8 * cause));
+			ivar = IXGBE_READ_REG(hw,
+			    IXGBE_IVAR(intr_alloc_entry >> 1));
+			ivar &= ~(0xFF << index);
+			ivar |= (msix_vector << index);
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR(intr_alloc_entry >> 1),
+			    ivar);
+		}
+		break;
+	default:
+		break;
+	}
 }
 
 /*
  * ixgbe_enable_ivar - Enable the given entry by setting the VAL bit of
  * given interrupt vector allocation register (IVAR).
+ * cause:
+ *   -1 : other cause
+ *    0 : rx
+ *    1 : tx
  */
 static void
-ixgbe_enable_ivar(ixgbe_t *ixgbe, uint16_t intr_alloc_entry)
+ixgbe_enable_ivar(ixgbe_t *ixgbe, uint16_t intr_alloc_entry, int8_t cause)
 {
 	struct ixgbe_hw *hw = &ixgbe->hw;
 	u32 ivar, index;
 
-	index = (intr_alloc_entry >> 2) & 0x1F;
-	ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
-	ivar |= (IXGBE_IVAR_ALLOC_VAL << (8 * (intr_alloc_entry & 0x3)));
-	IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		if (cause == -1) {
+			cause = 0;
+		}
+		index = (((cause * 64) + intr_alloc_entry) >> 2) & 0x1F;
+		ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
+		ivar |= (IXGBE_IVAR_ALLOC_VAL << (8 *
+		    (intr_alloc_entry & 0x3)));
+		IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+		break;
+	case ixgbe_mac_82599EB:
+		if (cause == -1) {
+			/* other causes */
+			index = (intr_alloc_entry & 1) * 8;
+			ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC);
+			ivar |= (IXGBE_IVAR_ALLOC_VAL << index);
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, ivar);
+		} else {
+			/* tx or rx causes */
+			index = ((16 * (intr_alloc_entry & 1)) + (8 * cause));
+			ivar = IXGBE_READ_REG(hw,
+			    IXGBE_IVAR(intr_alloc_entry >> 1));
+			ivar |= (IXGBE_IVAR_ALLOC_VAL << index);
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR(intr_alloc_entry >> 1),
+			    ivar);
+		}
+		break;
+	default:
+		break;
+	}
 }
 
 /*
- * ixgbe_enable_ivar - Disble the given entry by clearing the VAL bit of
+ * ixgbe_disable_ivar - Disble the given entry by clearing the VAL bit of
  * given interrupt vector allocation register (IVAR).
+ * cause:
+ *   -1 : other cause
+ *    0 : rx
+ *    1 : tx
  */
 static void
-ixgbe_disable_ivar(ixgbe_t *ixgbe, uint16_t intr_alloc_entry)
+ixgbe_disable_ivar(ixgbe_t *ixgbe, uint16_t intr_alloc_entry, int8_t cause)
 {
 	struct ixgbe_hw *hw = &ixgbe->hw;
 	u32 ivar, index;
 
-	index = (intr_alloc_entry >> 2) & 0x1F;
-	ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
-	ivar &= ~(IXGBE_IVAR_ALLOC_VAL << (8 * (intr_alloc_entry & 0x3)));
-	IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		if (cause == -1) {
+			cause = 0;
+		}
+		index = (((cause * 64) + intr_alloc_entry) >> 2) & 0x1F;
+		ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
+		ivar &= ~(IXGBE_IVAR_ALLOC_VAL<< (8 *
+		    (intr_alloc_entry & 0x3)));
+		IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+		break;
+	case ixgbe_mac_82599EB:
+		if (cause == -1) {
+			/* other causes */
+			index = (intr_alloc_entry & 1) * 8;
+			ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC);
+			ivar &= ~(IXGBE_IVAR_ALLOC_VAL << index);
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, ivar);
+		} else {
+			/* tx or rx causes */
+			index = ((16 * (intr_alloc_entry & 1)) + (8 * cause));
+			ivar = IXGBE_READ_REG(hw,
+			    IXGBE_IVAR(intr_alloc_entry >> 1));
+			ivar &= ~(IXGBE_IVAR_ALLOC_VAL << index);
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR(intr_alloc_entry >> 1),
+			    ivar);
+		}
+		break;
+	default:
+		break;
+	}
 }
 
 /*
- * ixgbe_map_rings_to_vectors - Map descriptor rings to interrupt vectors.
+ * ixgbe_map_intrs_to_vectors - Map different interrupts to MSI-X vectors.
  *
- * For MSI-X, here will map rx and tx ring to vector[0 - (vectors -1)].
- * The last vector will be used for other interrupt.
+ * For MSI-X, here will map rx interrupt, tx interrupt and other interrupt
+ * to vector[0 - (intr_cnt -1)].
  */
 static int
-ixgbe_map_rings_to_vectors(ixgbe_t *ixgbe)
+ixgbe_map_intrs_to_vectors(ixgbe_t *ixgbe)
 {
 	int i, vector = 0;
 
 	/* initialize vector map */
 	bzero(&ixgbe->vect_map, sizeof (ixgbe->vect_map));
+	for (i = 0; i < ixgbe->intr_cnt; i++) {
+		ixgbe->vect_map[i].ixgbe = ixgbe;
+	}
 
 	/*
 	 * non-MSI-X case is very simple: rx rings[0] on RTxQ[0],
@@ -3810,23 +4068,31 @@
 	}
 
 	/*
-	 * Ring/vector mapping for MSI-X
+	 * Interrupts/vectors mapping for MSI-X
 	 */
 
 	/*
-	 * Map vectors to rx rings
+	 * Map other interrupt to vector 0,
+	 * Set bit in map and count the bits set.
+	 */
+	BT_SET(ixgbe->vect_map[vector].other_map, 0);
+	ixgbe->vect_map[vector].other_cnt++;
+	vector++;
+
+	/*
+	 * Map rx ring interrupts to vectors
 	 */
 	for (i = 0; i < ixgbe->num_rx_rings; i++) {
 		ixgbe_map_rxring_to_vector(ixgbe, i, vector);
-		vector = (vector +1) % (ixgbe->intr_cnt -1);
+		vector = (vector +1) % ixgbe->intr_cnt;
 	}
 
 	/*
-	 * Map vectors to tx rings
+	 * Map tx ring interrupts to vectors
 	 */
 	for (i = 0; i < ixgbe->num_tx_rings; i++) {
 		ixgbe_map_txring_to_vector(ixgbe, i, vector);
-		vector = (vector +1) % (ixgbe->intr_cnt -1);
+		vector = (vector +1) % ixgbe->intr_cnt;
 	}
 
 	return (IXGBE_SUCCESS);
@@ -3842,31 +4108,43 @@
 ixgbe_setup_adapter_vector(ixgbe_t *ixgbe)
 {
 	struct ixgbe_hw *hw = &ixgbe->hw;
-	ixgbe_ring_vector_t *vect;	/* vector bitmap */
+	ixgbe_intr_vector_t *vect;	/* vector bitmap */
 	int r_idx;	/* ring index */
 	int v_idx;	/* vector index */
 
 	/*
 	 * Clear any previous entries
 	 */
-	for (v_idx = 0; v_idx < IXGBE_IVAR_REG_NUM; v_idx++)
-		IXGBE_WRITE_REG(hw, IXGBE_IVAR(v_idx), 0);
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		for (v_idx = 0; v_idx < 25; v_idx++)
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR(v_idx), 0);
+
+		break;
+	case ixgbe_mac_82599EB:
+		for (v_idx = 0; v_idx < 64; v_idx++)
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR(v_idx), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, 0);
+
+		break;
+	default:
+		break;
+	}
 
 	/*
 	 * For non MSI-X interrupt, rx rings[0] will use RTxQ[0], and
 	 * tx rings[0] will use RTxQ[1].
 	 */
 	if (ixgbe->intr_type != DDI_INTR_TYPE_MSIX) {
-		ixgbe_setup_ivar(ixgbe, IXGBE_IVAR_RX_QUEUE(0), 0);
-		ixgbe_setup_ivar(ixgbe, IXGBE_IVAR_TX_QUEUE(0), 1);
+		ixgbe_setup_ivar(ixgbe, 0, 0, 0);
+		ixgbe_setup_ivar(ixgbe, 0, 1, 1);
 		return;
 	}
 
 	/*
-	 * For MSI-X interrupt, "Other" is always on last vector.
+	 * For MSI-X interrupt, "Other" is always on vector[0].
 	 */
-	ixgbe_setup_ivar(ixgbe, IXGBE_IVAR_OTHER_CAUSES_INDEX,
-	    (ixgbe->intr_cnt - 1));
+	ixgbe_setup_ivar(ixgbe, IXGBE_IVAR_OTHER_CAUSES_INDEX, 0, -1);
 
 	/*
 	 * For each interrupt vector, populate the IVAR table
@@ -3881,8 +4159,7 @@
 		    (ixgbe->num_rx_rings - 1));
 
 		while (r_idx >= 0) {
-			ixgbe_setup_ivar(ixgbe, IXGBE_IVAR_RX_QUEUE(r_idx),
-			    v_idx);
+			ixgbe_setup_ivar(ixgbe, r_idx, v_idx, 0);
 			r_idx = bt_getlowbit(vect->rx_map, (r_idx + 1),
 			    (ixgbe->num_rx_rings - 1));
 		}
@@ -3894,8 +4171,7 @@
 		    (ixgbe->num_tx_rings - 1));
 
 		while (r_idx >= 0) {
-			ixgbe_setup_ivar(ixgbe, IXGBE_IVAR_TX_QUEUE(r_idx),
-			    v_idx);
+			ixgbe_setup_ivar(ixgbe, r_idx, v_idx, 1);
 			r_idx = bt_getlowbit(vect->tx_map, (r_idx + 1),
 			    (ixgbe->num_tx_rings - 1));
 		}
@@ -4354,7 +4630,7 @@
 	 * To enable interrupt by setting the VAL bit of given interrupt
 	 * vector allocation register (IVAR).
 	 */
-	ixgbe_enable_ivar(ixgbe, IXGBE_IVAR_RX_QUEUE(r_idx));
+	ixgbe_enable_ivar(ixgbe, r_idx, 0);
 
 	BT_SET(ixgbe->vect_map[v_idx].rx_map, r_idx);
 	mutex_exit(&ixgbe->gen_lock);
@@ -4381,7 +4657,7 @@
 	 * To disable interrupt by clearing the VAL bit of given interrupt
 	 * vector allocation register (IVAR).
 	 */
-	ixgbe_disable_ivar(ixgbe, IXGBE_IVAR_RX_QUEUE(r_idx));
+	ixgbe_disable_ivar(ixgbe, r_idx, 0);
 
 	BT_CLEAR(ixgbe->vect_map[v_idx].rx_map, r_idx);
 
--- a/usr/src/uts/common/io/ixgbe/ixgbe_osdep.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_osdep.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -22,12 +22,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include "ixgbe_osdep.h"
 #include "ixgbe_api.h"
 
@@ -36,3 +34,9 @@
 {
 	return (pci_config_get16(OS_DEP(hw)->cfg_handle, reg));
 }
+
+void
+ixgbe_write_pci_cfg(struct ixgbe_hw *hw, uint32_t reg, uint32_t val)
+{
+	pci_config_put16(OS_DEP(hw)->cfg_handle, reg, val);
+}
--- a/usr/src/uts/common/io/ixgbe/ixgbe_osdep.h	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_osdep.h	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
 #ifndef	_IXGBE_OSDEP_H
@@ -34,6 +34,7 @@
 #endif
 
 #include <sys/types.h>
+#include <sys/byteorder.h>
 #include <sys/conf.h>
 #include <sys/debug.h>
 #include <sys/stropts.h>
@@ -55,34 +56,18 @@
 /* function declarations */
 struct ixgbe_hw;
 uint16_t ixgbe_read_pci_cfg(struct ixgbe_hw *, uint32_t);
-
+void ixgbe_write_pci_cfg(struct ixgbe_hw *, uint32_t, uint32_t);
 
 #define	usec_delay(x)		drv_usecwait(x)
 #define	msec_delay(x)		drv_usecwait(x * 1000)
 
-#ifdef IXGBE_DEBUG
-#define	DEBUGOUT(S)		IXGBE_DEBUGLOG_0(NULL, S)
-#define	DEBUGOUT1(S, A)		IXGBE_DEBUGLOG_1(NULL, S, A)
-#define	DEBUGOUT2(S, A, B)	IXGBE_DEBUGLOG_2(NULL, S, A, B)
-#define	DEBUGOUT3(S, A, B, C)	IXGBE_DEBUGLOG_3(NULL, S, A, B, C)
-#define	DEBUGOUT6(S, A, B, C, D, E, F) \
-    IXGBE_DEBUGLOG_6(NULL, S, A, B, C, D, E, F)
-#define	DEBUGFUNC(F)		IXGBE_DEBUGLOG_1(NULL, "Entering %s", F)
-#else
-#define	DEBUGOUT(S)
-#define	DEBUGOUT1(S, A)
-#define	DEBUGOUT2(S, A, B)
-#define	DEBUGOUT3(S, A, B, C)
-#define	DEBUGOUT6(S, A, B, C, D, E, F)
-#define	DEBUGFUNC(F)
-#endif
-
 #define	OS_DEP(hw)		((struct ixgbe_osdep *)((hw)->back))
 
 #define	false		B_FALSE
 #define	true		B_TRUE
 
 #define	IXGBE_READ_PCIE_WORD 	ixgbe_read_pci_cfg
+#define	IXGBE_WRITE_PCIE_WORD 	ixgbe_write_pci_cfg
 #define	CMD_MEM_WRT_INVALIDATE	0x0010	/* BIT_4 */
 #define	PCI_COMMAND_REGISTER	0x04
 #define	PCI_EX_CONF_CAP		0xE0
@@ -103,7 +88,15 @@
 	ddi_get32((OS_DEP(a))->reg_handle, \
 	    (uint32_t *)((uintptr_t)(a)->hw_addr + reg))
 
+#define	IXGBE_WRITE_REG64(hw, reg, value)	\
+	do {								\
+		IXGBE_WRITE_REG(hw, reg, (u32) value);			\
+		IXGBE_WRITE_REG(hw, reg + 4, (u32) (value >> 32));	\
+		_NOTE(CONSTCOND)					\
+	} while (0)
+
 #define	msec_delay_irq	msec_delay
+#define	IXGBE_HTONL	htonl
 
 #define	UNREFERENCED_PARAMETER(x)	_NOTE(ARGUNUSED(x))
 
--- a/usr/src/uts/common/io/ixgbe/ixgbe_phy.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_phy.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,15 +23,27 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
-/* IntelVersion: 1.60 v2008-09-12 */
+/* IntelVersion: 1.83 v2-7-8_2009-4-7 */
 
 #include "ixgbe_api.h"
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
-#ident "$Id: ixgbe_phy.c,v 1.60 2008/09/15 15:47:02 mrchilak Exp $"
+
+static void ixgbe_i2c_start(struct ixgbe_hw *hw);
+static void ixgbe_i2c_stop(struct ixgbe_hw *hw);
+static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
+static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
+static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
+static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
+static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
+static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
+static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
+static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
+static bool ixgbe_get_i2c_data(u32 *i2cctl);
+void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
 
 /*
  * ixgbe_init_phy_ops_generic - Inits PHY function ptrs
@@ -53,6 +65,11 @@
 	phy->ops.setup_link_speed = &ixgbe_setup_phy_link_speed_generic;
 	phy->ops.check_link = NULL;
 	phy->ops.get_firmware_version = NULL;
+	phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_generic;
+	phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_generic;
+	phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic;
+	phy->ops.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic;
+	phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear;
 	phy->ops.identify_sfp = &ixgbe_identify_sfp_module_generic;
 	phy->sfp_type = ixgbe_sfp_type_unknown;
 
@@ -70,6 +87,7 @@
 {
 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
 	u32 phy_addr;
+	u16 ext_ability = 0;
 
 	if (hw->phy.type == ixgbe_phy_unknown) {
 		for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
@@ -78,10 +96,29 @@
 				(void) ixgbe_get_phy_id(hw);
 				hw->phy.type =
 				    ixgbe_get_phy_type_from_id(hw->phy.id);
+
+				if (hw->phy.type == ixgbe_phy_unknown) {
+					hw->phy.ops.read_reg(hw,
+					    IXGBE_MDIO_PHY_EXT_ABILITY,
+					    IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+					    &ext_ability);
+					if (ext_ability &
+					    IXGBE_MDIO_PHY_10GBASET_ABILITY ||
+					    ext_ability &
+					    IXGBE_MDIO_PHY_1000BASET_ABILITY)
+						hw->phy.type =
+						    ixgbe_phy_cu_unknown;
+					else
+						hw->phy.type =
+						    ixgbe_phy_generic;
+				}
+
 				status = IXGBE_SUCCESS;
 				break;
 			}
 		}
+		if (status != IXGBE_SUCCESS)
+			hw->phy.addr = 0;
 	} else {
 		status = IXGBE_SUCCESS;
 	}
@@ -175,13 +212,40 @@
 s32
 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
 {
+	u32 i;
+	u16 ctrl = 0;
+	s32 status = IXGBE_SUCCESS;
+
+	if (hw->phy.type == ixgbe_phy_unknown)
+		status = ixgbe_identify_phy_generic(hw);
+
+	if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none)
+		goto out;
+
 	/*
 	 * Perform soft PHY reset to the PHY_XS.
 	 * This will cause a soft reset to the PHY
 	 */
-	return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
+	hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
 	    IXGBE_MDIO_PHY_XS_DEV_TYPE,
 	    IXGBE_MDIO_PHY_XS_RESET);
+
+	/* Poll for reset bit to self-clear indicating reset is complete */
+	for (i = 0; i < 500; i++) {
+		msec_delay(1);
+		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
+		    IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl);
+		if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET))
+			break;
+	}
+
+	if (ctrl & IXGBE_MDIO_PHY_XS_RESET) {
+		status = IXGBE_ERR_RESET_FAILED;
+		DEBUGOUT("PHY reset polling failed to complete.\n");
+	}
+
+out:
+	return (status);
 }
 
 /*
@@ -472,6 +536,36 @@
 }
 
 /*
+ * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @autoneg: boolean auto-negotiation value
+ *
+ * Determines the link capabilities by reading the AUTOC register.
+ */
+s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
+    ixgbe_link_speed *speed, bool *autoneg)
+{
+	s32 status = IXGBE_ERR_LINK_SETUP;
+	u16 speed_ability;
+
+	*speed = 0;
+	*autoneg = true;
+
+	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
+	    IXGBE_MDIO_PMA_PMD_DEV_TYPE, &speed_ability);
+
+	if (status == IXGBE_SUCCESS) {
+		if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	}
+
+	return (status);
+}
+
+/*
  * ixgbe_check_phy_link_tnx - Determine link and speed status
  * @hw: pointer to hardware structure
  *
@@ -634,31 +728,40 @@
 }
 
 /*
- * ixgbe_identify_sfp_module_generic - Identifies SFP module and assigns
- * the PHY type.
+ * ixgbe_identify_sfp_module_generic - Identifies SFP module
  * @hw: pointer to hardware structure
  *
- * Searches for and identifies the SFP module.  Assigns appropriate PHY type.
+ * Searches for and identifies the SFP module and assigns appropriate PHY type.
  */
 s32
 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 {
 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
 	u32 vendor_oui = 0;
+	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
 	u8 identifier = 0;
 	u8 comp_codes_1g = 0;
 	u8 comp_codes_10g = 0;
-	u8 oui_bytes[4] = {0, 0, 0, 0};
+	u8 oui_bytes[3] = {0, 0, 0};
 	u8 transmission_media = 0;
+	u16 enforce_sfp = 0;
 
 	status = hw->phy.ops.read_i2c_eeprom(hw,
 	    IXGBE_SFF_IDENTIFIER, &identifier);
 
-	if (status == IXGBE_ERR_SFP_NOT_PRESENT) {
+	if (status == IXGBE_ERR_SFP_NOT_PRESENT || status == IXGBE_ERR_I2C) {
+		status = IXGBE_ERR_SFP_NOT_PRESENT;
 		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+		if (hw->phy.type != ixgbe_phy_nl) {
+			hw->phy.id = 0;
+			hw->phy.type = ixgbe_phy_unknown;
+		}
 		goto out;
 	}
 
+	/* LAN ID is needed for sfp_type determination */
+	hw->mac.ops.set_lan_id(hw);
+
 	if (identifier == IXGBE_SFF_IDENTIFIER_SFP) {
 		hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_1GBE_COMP_CODES,
 		    &comp_codes_1g);
@@ -673,18 +776,58 @@
 		 * 0    SFP_DA_CU
 		 * 1    SFP_SR
 		 * 2    SFP_LR
+		 * 3	SFP_DA_CORE0 - 82599-specific
+		 * 4	SFP_DA_CORE1 - 82599-specific
+		 * 5	SFP_SR/LR_CORE0 - 82599-specific
+		 * 6	SFP_SR/LR_CORE1 - 82599-specific
 		 */
-		if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
-			hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
-		else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
-			hw->phy.sfp_type = ixgbe_sfp_type_sr;
-		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
-			hw->phy.sfp_type = ixgbe_sfp_type_lr;
-		else
-			hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+		if (hw->mac.type == ixgbe_mac_82598EB) {
+			if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+				hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+				hw->phy.sfp_type = ixgbe_sfp_type_sr;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+				hw->phy.sfp_type = ixgbe_sfp_type_lr;
+			else
+				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+		} else if (hw->mac.type == ixgbe_mac_82599EB) {
+			if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+				if (hw->bus.lan_id == 0)
+					hw->phy.sfp_type =
+					    ixgbe_sfp_type_da_cu_core0;
+				else
+					hw->phy.sfp_type =
+					    ixgbe_sfp_type_da_cu_core1;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+				if (hw->bus.lan_id == 0)
+					hw->phy.sfp_type =
+					    ixgbe_sfp_type_srlr_core0;
+				else
+					hw->phy.sfp_type =
+					    ixgbe_sfp_type_srlr_core1;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+				if (hw->bus.lan_id == 0)
+					hw->phy.sfp_type =
+					    ixgbe_sfp_type_srlr_core0;
+				else
+					hw->phy.sfp_type =
+					    ixgbe_sfp_type_srlr_core1;
+			else
+				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+		}
+
+		if (hw->phy.sfp_type != stored_sfp_type)
+			hw->phy.sfp_setup_needed = true;
+
+		/* Determine if the SFP+ PHY is dual speed or not. */
+		if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
+		    (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
+		    ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
+		    (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
+			hw->phy.multispeed_fiber = true;
 
 		/* Determine PHY vendor */
-		if (hw->phy.type == ixgbe_phy_unknown) {
+		if (hw->phy.type != ixgbe_phy_nl) {
 			hw->phy.id = identifier;
 			hw->phy.ops.read_i2c_eeprom(hw,
 			    IXGBE_SFF_VENDOR_OUI_BYTE0, &oui_bytes[0]);
@@ -711,6 +854,9 @@
 			case IXGBE_SFF_VENDOR_OUI_AVAGO:
 				hw->phy.type = ixgbe_phy_sfp_avago;
 				break;
+			case IXGBE_SFF_VENDOR_OUI_INTEL:
+				hw->phy.type = ixgbe_phy_sfp_intel;
+				break;
 			default:
 				if (transmission_media &
 				    IXGBE_SFF_TWIN_AX_CAPABLE)
@@ -720,7 +866,29 @@
 				break;
 			}
 		}
-		status = IXGBE_SUCCESS;
+
+		if (hw->mac.type == ixgbe_mac_82598EB ||
+		    (hw->phy.sfp_type != ixgbe_sfp_type_sr &&
+		    hw->phy.sfp_type != ixgbe_sfp_type_lr &&
+		    hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 &&
+		    hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) {
+			status = IXGBE_SUCCESS;
+			goto out;
+		}
+
+		(void) ixgbe_get_device_caps(hw, &enforce_sfp);
+		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
+			/* Make sure we're a supported PHY type */
+			if (hw->phy.type == ixgbe_phy_sfp_intel) {
+				status = IXGBE_SUCCESS;
+			} else {
+				DEBUGOUT("SFP+ module not supported\n");
+				hw->phy.type = ixgbe_phy_sfp_unsupported;
+				status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+			}
+		} else {
+			status = IXGBE_SUCCESS;
+		}
 	}
 
 out:
@@ -729,12 +897,13 @@
 
 
 /*
- * ixgbe_get_sfp_init_sequence_offsets - Checks the MAC's EEPROM to see
- * if it supports a given SFP+ module type, if so it returns the offsets to the
- * phy init sequence block.
+ * ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence
  * @hw: pointer to hardware structure
  * @list_offset: offset to the SFP ID list
  * @data_offset: offset to the SFP data block
+ *
+ * Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if
+ * so it returns the offsets to the phy init sequence block.
  */
 s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
     u16 *list_offset, u16 *data_offset)
@@ -755,7 +924,7 @@
 	hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
 
 	if ((!*list_offset) || (*list_offset == 0xFFFF))
-		return (IXGBE_ERR_PHY);
+		return (IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT);
 
 	/* Shift offset to first ID word */
 	(*list_offset)++;
@@ -790,3 +959,564 @@
 
 	return (IXGBE_SUCCESS);
 }
+
+/*
+ * ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to read
+ * @eeprom_data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface.
+ */
+s32
+ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+    u8 *eeprom_data)
+{
+	DEBUGFUNC("ixgbe_read_i2c_eeprom_generic");
+
+	return (hw->phy.ops.read_i2c_byte(hw, byte_offset,
+	    IXGBE_I2C_EEPROM_DEV_ADDR, eeprom_data));
+}
+
+/*
+ * ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to write
+ * @eeprom_data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface.
+ */
+s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+    u8 eeprom_data)
+{
+	DEBUGFUNC("ixgbe_write_i2c_eeprom_generic");
+
+	return (hw->phy.ops.write_i2c_byte(hw, byte_offset,
+	    IXGBE_I2C_EEPROM_DEV_ADDR, eeprom_data));
+}
+
+/*
+ * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface at
+ * a specified deivce address.
+ */
+s32
+ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+    u8 dev_addr, u8 *data)
+{
+	s32 status = IXGBE_SUCCESS;
+	u32 max_retry = 1;
+	u32 retry = 0;
+	u16 swfw_mask = 0;
+	bool nack = 1;
+
+	DEBUGFUNC("ixgbe_read_i2c_byte_generic");
+
+	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
+		swfw_mask = IXGBE_GSSR_PHY1_SM;
+	else
+		swfw_mask = IXGBE_GSSR_PHY0_SM;
+
+	if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) {
+		status = IXGBE_ERR_SWFW_SYNC;
+		goto read_byte_out;
+	}
+
+	do {
+		ixgbe_i2c_start(hw);
+
+		/* Device Address and write indication */
+		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		ixgbe_i2c_start(hw);
+
+		/* Device Address and read indication */
+		status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_clock_in_i2c_byte(hw, data);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_clock_out_i2c_bit(hw, nack);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		ixgbe_i2c_stop(hw);
+		break;
+
+fail:
+		ixgbe_i2c_bus_clear(hw);
+		retry++;
+		if (retry < max_retry)
+			DEBUGOUT("I2C byte read error - Retrying.\n");
+		else
+			DEBUGOUT("I2C byte read error.\n");
+	} while (retry < max_retry);
+
+	ixgbe_release_swfw_sync(hw, swfw_mask);
+
+read_byte_out:
+	return (status);
+}
+
+/*
+ * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ */
+s32
+ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+    u8 dev_addr, u8 data)
+{
+	s32 status = IXGBE_SUCCESS;
+	u32 max_retry = 1;
+	u32 retry = 0;
+	u16 swfw_mask = 0;
+
+	DEBUGFUNC("ixgbe_write_i2c_byte_generic");
+
+	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
+		swfw_mask = IXGBE_GSSR_PHY1_SM;
+	else
+		swfw_mask = IXGBE_GSSR_PHY0_SM;
+
+	if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) {
+		status = IXGBE_ERR_SWFW_SYNC;
+		goto write_byte_out;
+	}
+
+	do {
+		ixgbe_i2c_start(hw);
+
+		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_clock_out_i2c_byte(hw, data);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != IXGBE_SUCCESS)
+			goto fail;
+
+		ixgbe_i2c_stop(hw);
+		break;
+
+fail:
+		ixgbe_i2c_bus_clear(hw);
+		retry++;
+		if (retry < max_retry)
+			DEBUGOUT("I2C byte write error - Retrying.\n");
+		else
+			DEBUGOUT("I2C byte write error.\n");
+	} while (retry < max_retry);
+
+	ixgbe_release_swfw_sync(hw, swfw_mask);
+
+write_byte_out:
+	return (status);
+}
+
+/*
+ * ixgbe_i2c_start - Sets I2C start condition
+ * @hw: pointer to hardware structure
+ *
+ * Sets I2C start condition (High -> Low on SDA while SCL is High)
+ */
+static void
+ixgbe_i2c_start(struct ixgbe_hw *hw)
+{
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+	DEBUGFUNC("ixgbe_i2c_start");
+
+	/* Start condition must begin with data and clock high */
+	(void) ixgbe_set_i2c_data(hw, &i2cctl, 1);
+	(void) ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+	/* Setup time for start condition (4.7us) */
+	usec_delay(IXGBE_I2C_T_SU_STA);
+
+	(void) ixgbe_set_i2c_data(hw, &i2cctl, 0);
+
+	/* Hold time for start condition (4us) */
+	usec_delay(IXGBE_I2C_T_HD_STA);
+
+	ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+	/* Minimum low period of clock is 4.7 us */
+	usec_delay(IXGBE_I2C_T_LOW);
+}
+
+/*
+ * ixgbe_i2c_stop - Sets I2C stop condition
+ * @hw: pointer to hardware structure
+ *
+ * Sets I2C stop condition (Low -> High on SDA while SCL is High)
+ */
+static void
+ixgbe_i2c_stop(struct ixgbe_hw *hw)
+{
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+	DEBUGFUNC("ixgbe_i2c_stop");
+
+	/* Stop condition must begin with data low and clock high */
+	(void) ixgbe_set_i2c_data(hw, &i2cctl, 0);
+	(void) ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+	/* Setup time for stop condition (4us) */
+	usec_delay(IXGBE_I2C_T_SU_STO);
+
+	(void) ixgbe_set_i2c_data(hw, &i2cctl, 1);
+
+	/* bus free time between stop and start (4.7us) */
+	usec_delay(IXGBE_I2C_T_BUF);
+}
+
+/*
+ * ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
+ * @hw: pointer to hardware structure
+ * @data: data byte to clock in
+ *
+ * Clocks in one byte data via I2C data/clock
+ */
+static s32
+ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
+{
+	s32 status = IXGBE_SUCCESS;
+	s32 i;
+	bool bit = 0;
+
+	DEBUGFUNC("ixgbe_clock_in_i2c_byte");
+
+	for (i = 7; i >= 0; i--) {
+		status = ixgbe_clock_in_i2c_bit(hw, &bit);
+		*data |= bit<<i;
+
+		if (status != IXGBE_SUCCESS)
+			break;
+	}
+
+	return (status);
+}
+
+/*
+ * ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
+ * @hw: pointer to hardware structure
+ * @data: data byte clocked out
+ *
+ * Clocks out one byte data via I2C data/clock
+ */
+static s32
+ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
+{
+	s32 status = IXGBE_SUCCESS;
+	s32 i;
+	u32 i2cctl;
+	bool bit = 0;
+
+	DEBUGFUNC("ixgbe_clock_out_i2c_byte");
+
+	for (i = 7; i >= 0; i--) {
+		bit = (data >> i) & 0x1;
+		status = ixgbe_clock_out_i2c_bit(hw, bit);
+
+		if (status != IXGBE_SUCCESS)
+			break;
+	}
+
+	/* Release SDA line (set high) */
+	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	i2cctl |= IXGBE_I2C_DATA_OUT;
+	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl);
+
+	return (status);
+}
+
+/*
+ * ixgbe_get_i2c_ack - Polls for I2C ACK
+ * @hw: pointer to hardware structure
+ *
+ * Clocks in/out one bit via I2C data/clock
+ */
+static s32
+ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
+{
+	s32 status;
+	u32 i = 0;
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	u32 timeout = 10;
+	bool ack = 1;
+
+	DEBUGFUNC("ixgbe_get_i2c_ack");
+
+	status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+	if (status != IXGBE_SUCCESS)
+		goto out;
+
+	/* Minimum high period of clock is 4us */
+	usec_delay(IXGBE_I2C_T_HIGH);
+
+	/*
+	 * Poll for ACK.  Note that ACK in I2C spec is
+	 * transition from 1 to 0
+	 */
+	for (i = 0; i < timeout; i++) {
+		i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+		ack = ixgbe_get_i2c_data(&i2cctl);
+
+		usec_delay(1);
+		if (ack == 0)
+			break;
+	}
+
+	if (ack == 1) {
+		DEBUGOUT("I2C ack was not received.\n");
+		status = IXGBE_ERR_I2C;
+	}
+
+	ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+	/* Minimum low period of clock is 4.7 us */
+	usec_delay(IXGBE_I2C_T_LOW);
+
+out:
+	return (status);
+}
+
+/*
+ * ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
+ * @hw: pointer to hardware structure
+ * @data: read data value
+ *
+ * Clocks in one bit via I2C data/clock
+ */
+static s32
+ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
+{
+	s32 status;
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+	status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+	/* Minimum high period of clock is 4us */
+	usec_delay(IXGBE_I2C_T_HIGH);
+
+	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	*data = ixgbe_get_i2c_data(&i2cctl);
+
+	ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+	/* Minimum low period of clock is 4.7 us */
+	usec_delay(IXGBE_I2C_T_LOW);
+
+	return (status);
+}
+
+/*
+ * ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
+ * @hw: pointer to hardware structure
+ * @data: data value to write
+ *
+ * Clocks out one bit via I2C data/clock
+ */
+static s32
+ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
+{
+	s32 status;
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+	status = ixgbe_set_i2c_data(hw, &i2cctl, data);
+	if (status == IXGBE_SUCCESS) {
+		status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+		/* Minimum high period of clock is 4us */
+		usec_delay(IXGBE_I2C_T_HIGH);
+
+		ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+		/*
+		 * Minimum low period of clock is 4.7 us.
+		 * This also takes care of the data hold time.
+		 */
+		usec_delay(IXGBE_I2C_T_LOW);
+	} else {
+		status = IXGBE_ERR_I2C;
+		DEBUGOUT1("I2C data was not set to %X\n", data);
+	}
+
+	return (status);
+}
+
+/*
+ * ixgbe_raise_i2c_clk - Raises the I2C SCL clock
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Raises the I2C clock line '0'->'1'
+ */
+static s32
+ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
+{
+	s32 status = IXGBE_SUCCESS;
+
+	*i2cctl |= IXGBE_I2C_CLK_OUT;
+
+	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+	/* SCL rise time (1000ns) */
+	usec_delay(IXGBE_I2C_T_RISE);
+
+	return (status);
+}
+
+/*
+ * ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Lowers the I2C clock line '1'->'0'
+ */
+static void
+ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
+{
+	*i2cctl &= ~IXGBE_I2C_CLK_OUT;
+
+	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+	/* SCL fall time (300ns) */
+	usec_delay(IXGBE_I2C_T_FALL);
+}
+
+/*
+ * ixgbe_set_i2c_data - Sets the I2C data bit
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ * @data: I2C data value (0 or 1) to set
+ *
+ * Sets the I2C data bit
+ */
+static s32
+ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
+{
+	s32 status = IXGBE_SUCCESS;
+
+	if (data)
+		*i2cctl |= IXGBE_I2C_DATA_OUT;
+	else
+		*i2cctl &= ~IXGBE_I2C_DATA_OUT;
+
+	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
+	usec_delay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
+
+	/* Verify data was set correctly */
+	*i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	if (data != ixgbe_get_i2c_data(i2cctl)) {
+		status = IXGBE_ERR_I2C;
+		DEBUGOUT1("Error - I2C data was not set to %X.\n", data);
+	}
+
+	return (status);
+}
+
+/*
+ * ixgbe_get_i2c_data - Reads the I2C SDA data bit
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Returns the I2C data bit value
+ */
+static bool
+ixgbe_get_i2c_data(u32 *i2cctl)
+{
+	bool data;
+
+	if (*i2cctl & IXGBE_I2C_DATA_IN)
+		data = 1;
+	else
+		data = 0;
+
+	return (data);
+}
+
+/*
+ * ixgbe_i2c_bus_clear - Clears the I2C bus
+ * @hw: pointer to hardware structure
+ *
+ * Clears the I2C bus by sending nine clock pulses.
+ * Used when data line is stuck low.
+ */
+void
+ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
+{
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	u32 i;
+
+	DEBUGFUNC("ixgbe_i2c_bus_clear");
+
+	ixgbe_i2c_start(hw);
+
+	(void) ixgbe_set_i2c_data(hw, &i2cctl, 1);
+
+	for (i = 0; i < 9; i++) {
+		(void) ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+		/* Min high period of clock is 4us */
+		usec_delay(IXGBE_I2C_T_HIGH);
+
+		ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+		/* Min low period of clock is 4.7us */
+		usec_delay(IXGBE_I2C_T_LOW);
+	}
+
+	ixgbe_i2c_start(hw);
+
+	/* Put the i2c bus back to default state */
+	ixgbe_i2c_stop(hw);
+}
--- a/usr/src/uts/common/io/ixgbe/ixgbe_phy.h	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_phy.h	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,10 +23,10 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
-/* IntelVersion: 1.27 v2008-09-12 */
+/* IntelVersion: 1.32 v2-7-8_2009-4-7 */
 
 #ifndef _IXGBE_PHY_H
 #define	_IXGBE_PHY_H
@@ -48,6 +48,7 @@
 /* Bitmasks */
 #define	IXGBE_SFF_TWIN_AX_CAPABLE	0x80
 #define	IXGBE_SFF_1GBASESX_CAPABLE	0x1
+#define	IXGBE_SFF_1GBASELX_CAPABLE	0x2
 #define	IXGBE_SFF_10GBASESR_CAPABLE	0x10
 #define	IXGBE_SFF_10GBASELR_CAPABLE	0x20
 #define	IXGBE_I2C_EEPROM_READ_MASK	0x100
@@ -58,16 +59,27 @@
 #define	IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS	0x3
 
 /* Bit-shift macros */
-#define	IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT	12
-#define	IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT	8
-#define	IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT	4
+#define	IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT	24
+#define	IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT	16
+#define	IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT	8
 
 /* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
 #define	IXGBE_SFF_VENDOR_OUI_TYCO	0x00407600
 #define	IXGBE_SFF_VENDOR_OUI_FTL	0x00906500
 #define	IXGBE_SFF_VENDOR_OUI_AVAGO	0x00176A00
+#define	IXGBE_SFF_VENDOR_OUI_INTEL	0x001B2100
 
-#ident "$Id: ixgbe_phy.h,v 1.27 2008/09/02 18:20:19 mrchilak Exp $"
+/* I2C SDA and SCL timing parameters for standard mode */
+#define	IXGBE_I2C_T_HD_STA	4
+#define	IXGBE_I2C_T_LOW		5
+#define	IXGBE_I2C_T_HIGH	4
+#define	IXGBE_I2C_T_SU_STA	5
+#define	IXGBE_I2C_T_HD_DATA	5
+#define	IXGBE_I2C_T_SU_DATA	1
+#define	IXGBE_I2C_T_RISE	1
+#define	IXGBE_I2C_T_FALL	1
+#define	IXGBE_I2C_T_SU_STO	4
+#define	IXGBE_I2C_T_BUF		5
 
 s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
 bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
@@ -82,6 +94,8 @@
 s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw);
 s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
     ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete);
+s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
+    ixgbe_link_speed *speed, bool *autoneg);
 
 /* PHY specific */
 s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
@@ -93,5 +107,13 @@
 s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
 s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
     u16 *list_offset, u16 *data_offset);
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+    u8 dev_addr, u8 *data);
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+    u8 dev_addr, u8 data);
+s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+    u8 *eeprom_data);
+s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+    u8 eeprom_data);
 
 #endif /* _IXGBE_PHY_H */
--- a/usr/src/uts/common/io/ixgbe/ixgbe_rx.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_rx.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,6 +1,7 @@
 /*
  * CDDL HEADER START
  *
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -20,10 +21,6 @@
  */
 
 /*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
@@ -67,13 +64,9 @@
 	 * Using the recycled data buffer to generate a new mblk
 	 */
 	recycle_rcb->mp = desballoc((unsigned char *)
-	    (recycle_rcb->rx_buf.address - IPHDR_ALIGN_ROOM),
-	    (recycle_rcb->rx_buf.size + IPHDR_ALIGN_ROOM),
+	    recycle_rcb->rx_buf.address,
+	    recycle_rcb->rx_buf.size,
 	    0, &recycle_rcb->free_rtn);
-	if (recycle_rcb->mp != NULL) {
-		recycle_rcb->mp->b_rptr += IPHDR_ALIGN_ROOM;
-		recycle_rcb->mp->b_wptr += IPHDR_ALIGN_ROOM;
-	}
 
 	/*
 	 * Put the recycled rx control block into free list
@@ -168,18 +161,15 @@
 	 */
 	if (current_rcb->mp == NULL) {
 		current_rcb->mp = desballoc((unsigned char *)
-		    (current_rcb->rx_buf.address - IPHDR_ALIGN_ROOM),
-		    (current_rcb->rx_buf.size + IPHDR_ALIGN_ROOM),
+		    current_rcb->rx_buf.address,
+		    current_rcb->rx_buf.size,
 		    0, &current_rcb->free_rtn);
 		/*
 		 * If it is failed to built a mblk using the current
 		 * DMA buffer, we have to return and use bcopy to
 		 * process the packet.
 		 */
-		if (current_rcb->mp != NULL) {
-			current_rcb->mp->b_rptr += IPHDR_ALIGN_ROOM;
-			current_rcb->mp->b_wptr += IPHDR_ALIGN_ROOM;
-		} else {
+		if (current_rcb->mp == NULL) {
 			atomic_inc_32(&rx_ring->rcb_free);
 			return (NULL);
 		}
@@ -379,7 +369,6 @@
 	 * Update the h/w tail accordingly
 	 */
 	rx_tail = PREV_INDEX(rx_next, 1, rx_ring->ring_size);
-
 	IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_RDT(rx_ring->index), rx_tail);
 
 	if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
--- a/usr/src/uts/common/io/ixgbe/ixgbe_stat.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_stat.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,6 +1,7 @@
 /*
  * CDDL HEADER START
  *
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -20,10 +21,6 @@
  */
 
 /*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
@@ -106,8 +103,15 @@
 		ixgbe_ks->qbrc[i].value.ui64 +=
 		    IXGBE_READ_REG(hw, IXGBE_QBRC(i));
 		ixgbe_ks->tor.value.ui64 += ixgbe_ks->qbrc[i].value.ui64;
-		ixgbe_ks->qbtc[i].value.ui64 +=
-		    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+		if (hw->mac.type >= ixgbe_mac_82599EB) {
+			ixgbe_ks->qbtc[i].value.ui64 +=
+			    IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
+			ixgbe_ks->qbtc[i].value.ui64 += ((uint64_t)
+			    (IXGBE_READ_REG(hw, IXGBE_QBTC_H(i))) << 32);
+		} else {
+			ixgbe_ks->qbtc[i].value.ui64 +=
+			    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+		}
 		ixgbe_ks->tot.value.ui64 += ixgbe_ks->qbtc[i].value.ui64;
 	}
 	/*
@@ -144,9 +148,21 @@
 	ixgbe_ks->mrfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MRFC);
 	ixgbe_ks->rlec.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RLEC);
 	ixgbe_ks->lxontxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONTXC);
-	ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
+	if (hw->mac.type == ixgbe_mac_82598EB) {
+		ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
+		    IXGBE_LXONRXC);
+	} else {
+		ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
+		    IXGBE_LXONRXCNT);
+	}
 	ixgbe_ks->lxofftxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
-	ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+	if (hw->mac.type == ixgbe_mac_82598EB) {
+		ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
+		    IXGBE_LXOFFRXC);
+	} else {
+		ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
+		    IXGBE_LXOFFRXCNT);
+	}
 	ixgbe_ks->ruc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RUC);
 	ixgbe_ks->rfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RFC);
 	ixgbe_ks->roc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_ROC);
--- a/usr/src/uts/common/io/ixgbe/ixgbe_sw.h	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_sw.h	Sun Apr 12 18:46:02 2009 +0800
@@ -1,6 +1,7 @@
 /*
  * CDDL HEADER START
  *
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -20,10 +21,6 @@
  */
 
 /*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
@@ -94,13 +91,15 @@
 #define	MAX_COOKIE			18
 #define	MIN_NUM_TX_DESC			2
 
+#define	IXGBE_ADAPTER_REGSET		1	/* map adapter registers */
+
 /*
- * MAX_xx_QUEUE_NUM and MAX_RING_VECTOR values need to be the maximum of all
+ * MAX_xx_QUEUE_NUM and MAX_INTR_VECTOR values need to be the maximum of all
  * supported silicon types.
  */
-#define	MAX_TX_QUEUE_NUM		32
-#define	MAX_RX_QUEUE_NUM		64
-#define	MAX_RING_VECTOR			16
+#define	MAX_TX_QUEUE_NUM		128
+#define	MAX_RX_QUEUE_NUM		128
+#define	MAX_INTR_VECTOR			64
 
 /*
  * Maximum values for user configurable parameters
@@ -111,7 +110,8 @@
 
 #define	MAX_MTU				16366
 #define	MAX_RX_LIMIT_PER_INTR		4096
-#define	MAX_INTR_THROTTLING		65535
+#define	MAX_INTR_THROTTLING_82598	65535
+#define	MAX_INTR_THROTTLING_82599	0x7FC
 
 #define	MAX_RX_COPY_THRESHOLD		9216
 #define	MAX_TX_COPY_THRESHOLD		9216
@@ -144,7 +144,8 @@
 
 #define	DEFAULT_MTU			ETHERMTU
 #define	DEFAULT_RX_LIMIT_PER_INTR	256
-#define	DEFAULT_INTR_THROTTLING		200	/* In unit of 256 nsec */
+#define	DEFAULT_INTR_THROTTLING_82598	200	/* In unit of 256 nsec */
+#define	DEFAULT_INTR_THROTTLING_82599	26	/* In unit of 2 usec */
 #define	DEFAULT_RX_COPY_THRESHOLD	128
 #define	DEFAULT_TX_COPY_THRESHOLD	512
 #define	DEFAULT_TX_RECYCLE_THRESHOLD	(MAX_COOKIE + 1)
@@ -267,6 +268,7 @@
 
 /* bits representing all interrupt types other than tx & rx */
 #define	IXGBE_OTHER_INTR	0x3ff00000
+#define	IXGBE_82599_OTHER_INTR	0x86100000
 
 /*
  * Shorthand for the NDD parameters
@@ -643,15 +645,17 @@
 } ixgbe_rx_group_t;
 
 /*
- * structure to map ring cleanup to msi-x vector
+ * structure to map interrupt cleanup to msi-x vector
  */
-typedef struct ixgbe_ring_vector {
+typedef struct ixgbe_intr_vector {
 	struct ixgbe *ixgbe;	/* point to my adapter */
 	ulong_t rx_map[BT_BITOUL(MAX_RX_QUEUE_NUM)];	/* bitmap of rx rings */
 	int	rxr_cnt;	/* count rx rings */
 	ulong_t tx_map[BT_BITOUL(MAX_TX_QUEUE_NUM)];	/* bitmap of tx rings */
 	int	txr_cnt;	/* count tx rings */
-} ixgbe_ring_vector_t;
+	ulong_t other_map[BT_BITOUL(2)];		/* bitmap of other */
+	int	other_cnt;	/* count other interrupt */
+} ixgbe_intr_vector_t;
 
 /*
  * Software adapter state
@@ -666,6 +670,8 @@
 	adapter_info_t		*capab;	/* adapter hardware capabilities */
 	ddi_taskq_t		*lsc_taskq;	/* link-status-change taskq */
 	uint32_t		eims;		/* interrupt mask setting */
+	uint32_t		eimc;		/* interrupt mask clear */
+	uint32_t		eicr;		/* interrupt cause reg */
 
 	uint32_t		ixgbe_state;
 	link_state_t		link_state;
@@ -680,9 +686,9 @@
 	uint32_t		max_frame_size;
 
 	/*
-	 * Each msi-x vector: map vector to ring cleanup
+	 * Each msi-x vector: map vector to interrupt cleanup
 	 */
-	ixgbe_ring_vector_t	vect_map[MAX_RING_VECTOR];
+	ixgbe_intr_vector_t	vect_map[MAX_INTR_VECTOR];
 
 	/*
 	 * Receive Rings
@@ -717,7 +723,7 @@
 	boolean_t		rx_hcksum_enable; /* Rx h/w cksum offload */
 	uint32_t		rx_copy_thresh; /* Rx copy threshold */
 	uint32_t		rx_limit_per_intr; /* Rx pkts per interrupt */
-	uint32_t		intr_throttling[MAX_RING_VECTOR];
+	uint32_t		intr_throttling[MAX_INTR_VECTOR];
 	uint32_t		intr_force;
 	int			fm_capabilities; /* FMA capabilities */
 
--- a/usr/src/uts/common/io/ixgbe/ixgbe_tx.c	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_tx.c	Sun Apr 12 18:46:02 2009 +0800
@@ -1,6 +1,7 @@
 /*
  * CDDL HEADER START
  *
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -20,11 +21,7 @@
  */
 
 /*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -43,7 +40,7 @@
 static boolean_t ixgbe_check_context(ixgbe_tx_ring_t *,
     ixgbe_tx_context_t *);
 static void ixgbe_fill_context(struct ixgbe_adv_tx_context_desc *,
-    ixgbe_tx_context_t *, int);
+    ixgbe_tx_context_t *);
 
 #ifndef IXGBE_DEBUG
 #pragma inline(ixgbe_save_desc)
@@ -125,8 +122,9 @@
 		 * If the mblk size exceeds the max size ixgbe could
 		 * process, then discard this mblk, and return NULL.
 		 */
-		if ((ctx->lso_flag && ((mbsize - ctx->mac_hdr_len)
-		    > IXGBE_LSO_MAXLEN)) || (!ctx->lso_flag &&
+		if ((ctx->lso_flag &&
+		    ((mbsize - ctx->mac_hdr_len) > IXGBE_LSO_MAXLEN)) ||
+		    (!ctx->lso_flag &&
 		    (mbsize > (ixgbe->max_frame_size - ETHERFCSL)))) {
 			freemsg(mp);
 			IXGBE_DEBUGLOG_0(ixgbe, "ixgbe_tx: packet oversize");
@@ -140,8 +138,9 @@
 	 * Check and recycle tx descriptors.
 	 * The recycle threshold here should be selected carefully
 	 */
-	if (tx_ring->tbd_free < tx_ring->recycle_thresh)
+	if (tx_ring->tbd_free < tx_ring->recycle_thresh) {
 		tx_ring->tx_recycle(tx_ring);
+	}
 
 	/*
 	 * After the recycling, if the tbd_free is less than the
@@ -200,7 +199,7 @@
 		 */
 		if ((nmp != mp) ||
 		    (P2NPHASE((uintptr_t)nmp->b_rptr, ixgbe->sys_page_size)
-		    < len)) {
+		    < hdr_len)) {
 			IXGBE_DEBUG_STAT(tx_ring->stat_lso_header_fail);
 			/*
 			 * reallocate the mblk for the last header fragment,
@@ -209,7 +208,7 @@
 			 */
 			new_mp = allocb(hdr_frag_len, NULL);
 			if (!new_mp)
-				return (B_FALSE);
+				return (mp);
 			bcopy(nmp->b_rptr, new_mp->b_rptr, hdr_frag_len);
 			/* link the new header fragment with the other parts */
 			new_mp->b_wptr = new_mp->b_rptr + hdr_frag_len;
@@ -569,8 +568,10 @@
 	hcksum_retrieve(mp, NULL, NULL, &start, NULL, NULL, NULL, &hckflags);
 	bzero(ctx, sizeof (ixgbe_tx_context_t));
 
-	if (hckflags == 0)
+	if (hckflags == 0) {
 		return (0);
+	}
+
 	ctx->hcksum_flags = hckflags;
 
 	lso_info_get(mp, &mss, &lsoflags);
@@ -771,7 +772,7 @@
  */
 static void
 ixgbe_fill_context(struct ixgbe_adv_tx_context_desc *ctx_tbd,
-    ixgbe_tx_context_t *ctx, int ring_index)
+    ixgbe_tx_context_t *ctx)
 {
 	/*
 	 * Fill the context descriptor with the checksum
@@ -808,12 +809,13 @@
 	}
 
 	ctx_tbd->seqnum_seed = 0;
-	ctx_tbd->mss_l4len_idx = ring_index << 4;
 
 	if (ctx->lso_flag) {
-		ctx_tbd->mss_l4len_idx |=
+		ctx_tbd->mss_l4len_idx =
 		    (ctx->l4_hdr_len << IXGBE_ADVTXD_L4LEN_SHIFT) |
 		    (ctx->mss << IXGBE_ADVTXD_MSS_SHIFT);
+	} else {
+		ctx_tbd->mss_l4len_idx = 0;
 	}
 }
 
@@ -870,8 +872,7 @@
 			 * hardware checksum offload informations.
 			 */
 			ixgbe_fill_context(
-			    (struct ixgbe_adv_tx_context_desc *)tbd,
-			    ctx, tx_ring->index);
+			    (struct ixgbe_adv_tx_context_desc *)tbd, ctx);
 
 			index = NEXT_INDEX(index, 1, tx_ring->ring_size);
 			desc_num++;
@@ -938,23 +939,35 @@
 	/*
 	 * The Insert Ethernet CRC (IFCS) bit and the checksum fields are only
 	 * valid in the first descriptor of the packet.
+	 * Setting paylen in every first_tbd for all parts.
+	 * 82599 requires the packet length in paylen field with or without
+	 * LSO and 82598 will ignore it in non-LSO mode.
 	 */
 	ASSERT(first_tbd != NULL);
 	first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_IFCS;
-	first_tbd->read.olinfo_status |= (tx_ring->index << 4);
 
-	if (ctx != NULL && ctx->lso_flag) {
-		first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
-		first_tbd->read.olinfo_status |=
-		    (mbsize - ctx->mac_hdr_len - ctx->ip_hdr_len
-		    - ctx->l4_hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT;
-	}
-
-	if (ctx != NULL && ctx->lso_flag) {
-		first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
-		first_tbd->read.olinfo_status |=
-		    (mbsize - ctx->mac_hdr_len - ctx->ip_hdr_len
-		    - ctx->l4_hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT;
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599EB:
+		if (ctx != NULL && ctx->lso_flag) {
+			first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
+			first_tbd->read.olinfo_status |=
+			    (mbsize - ctx->mac_hdr_len - ctx->ip_hdr_len
+			    - ctx->l4_hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT;
+		} else {
+			first_tbd->read.olinfo_status |=
+			    (mbsize << IXGBE_ADVTXD_PAYLEN_SHIFT);
+		}
+		break;
+	case ixgbe_mac_82598EB:
+		if (ctx != NULL && ctx->lso_flag) {
+			first_tbd->read.cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
+			first_tbd->read.olinfo_status |=
+			    (mbsize - ctx->mac_hdr_len - ctx->ip_hdr_len
+			    - ctx->l4_hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT;
+		}
+		break;
+	default:
+		break;
 	}
 
 	/* Set hardware checksum bits */
--- a/usr/src/uts/common/io/ixgbe/ixgbe_type.h	Sat Apr 11 23:27:09 2009 -0700
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_type.h	Sun Apr 12 18:46:02 2009 +0800
@@ -1,7 +1,7 @@
 /*
  * CDDL HEADER START
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
  * The contents of this file are subject to the terms of the
  * Common Development and Distribution License (the "License").
  * You may not use this file except in compliance with the License.
@@ -23,21 +23,22 @@
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms of the CDDL.
+ * Use is subject to license terms.
  */
 
-/* IntelVersion: 1.244 v2008-09-12 */
+/* IntelVersion: 1.316 v2-7-8_2009-4-7 */
 
 #ifndef _IXGBE_TYPE_H
 #define	_IXGBE_TYPE_H
 
 #include "ixgbe_osdep.h"
-#ident "$Id: ixgbe_type.h,v 1.244 2008/09/04 17:23:49 mrchilak Exp $"
 
 /* Vendor ID */
 #define	IXGBE_INTEL_VENDOR_ID   0x8086
 
 /* Device IDs */
+#define	IXGBE_DEV_ID_82598			0x10B6
+#define	IXGBE_DEV_ID_82598_BX			0x1508
 #define	IXGBE_DEV_ID_82598AF_DUAL_PORT		0x10C6
 #define	IXGBE_DEV_ID_82598AF_SINGLE_PORT	0x10C7
 #define	IXGBE_DEV_ID_82598AT			0x10C8
@@ -47,6 +48,11 @@
 #define	IXGBE_DEV_ID_82598_DA_DUAL_PORT		0x10F1
 #define	IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM	0x10E1
 #define	IXGBE_DEV_ID_82598EB_XF_LR		0x10F4
+#define	IXGBE_DEV_ID_82599_KX4			0x10F7
+#define	IXGBE_DEV_ID_82599_KX4_SIK		0x1514
+#define	IXGBE_DEV_ID_82599_CX4			0x10F9
+#define	IXGBE_DEV_ID_82599_SFP			0x10FB
+#define	IXGBE_DEV_ID_82599_SPW			0x1507
 
 /* General Registers */
 #define	IXGBE_CTRL	0x00000
@@ -54,9 +60,12 @@
 #define	IXGBE_CTRL_EXT	0x00018
 #define	IXGBE_ESDP	0x00020
 #define	IXGBE_EODSDP	0x00028
+#define	IXGBE_I2CCTL	0x00028
 #define	IXGBE_LEDCTL	0x00200
 #define	IXGBE_FRTIMER	0x00048
 #define	IXGBE_TCPTIMER	0x0004C
+#define	IXGBE_CORESPARE	0x00600
+#define	IXGBE_EXVET	0x05078
 
 /* NVM Registers */
 #define	IXGBE_EEC	0x10010
@@ -70,6 +79,19 @@
 #define	IXGBE_FLOP	0x1013C
 #define	IXGBE_GRC	0x10200
 
+/* General Receive Control */
+#define	IXGBE_GRC_MNG	0x00000001 /* Manageability Enable */
+#define	IXGBE_GRC_APME	0x00000002 /* Advanced Power Management Enable */
+
+#define	IXGBE_VPDDIAG0	0x10204
+#define	IXGBE_VPDDIAG1	0x10208
+
+/* I2CCTL Bit Masks */
+#define	IXGBE_I2C_CLK_IN	0x00000001
+#define	IXGBE_I2C_CLK_OUT	0x00000002
+#define	IXGBE_I2C_DATA_IN	0x00000004
+#define	IXGBE_I2C_DATA_OUT	0x00000008
+
 /* Interrupt Registers */
 #define	IXGBE_EICR	0x00800
 #define	IXGBE_EICS	0x00808
@@ -77,35 +99,66 @@
 #define	IXGBE_EIMC	0x00888
 #define	IXGBE_EIAC	0x00810
 #define	IXGBE_EIAM	0x00890
+#define	IXGBE_EICS_EX(_i)	(0x00A90 + (_i) * 4)
+#define	IXGBE_EIMS_EX(_i)	(0x00AA0 + (_i) * 4)
+#define	IXGBE_EIMC_EX(_i)	(0x00AB0 + (_i) * 4)
+#define	IXGBE_EIAM_EX(_i)	(0x00AD0 + (_i) * 4)
+/* 82599 EITR is only 12 bits, with the lower 3 always zero */
+/*
+ * 82598 EITR is 16 bits but set the limits based on the max
+ * supported by all ixgbe hardware
+ */
+#define	IXGBE_MAX_INT_RATE	488281
+#define	IXGBE_MIN_INT_RATE	956
+#define	IXGBE_MAX_EITR		0x00000FF8
+#define	IXGBE_MIN_EITR		8
 #define	IXGBE_EITR(_i)	(((_i) <= 23) ? \
 	(0x00820 + ((_i) * 4)) : (0x012300 + ((_i) * 4)))
+#define	IXGBE_EITR_ITR_INT_MASK	0x00000FF8
+#define	IXGBE_EITR_LLI_MOD	0x00008000
+#define	IXGBE_EITR_CNT_WDIS	0x80000000
 #define	IXGBE_IVAR(_i)	(0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
+#define	IXGBE_IVAR_MISC	0x00A00 /* misc MSI-X interrupt causes */
+#define	IXGBE_EITRSEL	0x00894
 #define	IXGBE_MSIXT	0x00000 /* MSI-X Table. 0x0000 - 0x01C */
 #define	IXGBE_MSIXPBA	0x02000 /* MSI-X Pending bit array */
 #define	IXGBE_PBACL(_i)	(((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4)))
 #define	IXGBE_GPIE	0x00898
 
 /* Flow Control Registers */
+#define	IXGBE_FCADBUL	0x03210
+#define	IXGBE_FCADBUH	0x03214
+#define	IXGBE_FCAMACL	0x04328
+#define	IXGBE_FCAMACH	0x0432C
+#define	IXGBE_FCRTH_82599(_i)	(0x03260 + ((_i) * 4)) /* 8 of these (0-7) */
+#define	IXGBE_FCRTL_82599(_i)	(0x03220 + ((_i) * 4)) /* 8 of these (0-7) */
 #define	IXGBE_PFCTOP    0x03008
 #define	IXGBE_FCTTV(_i)	(0x03200 + ((_i) * 4)) /* 4 of these (0-3) */
 #define	IXGBE_FCRTL(_i) (0x03220 + ((_i) * 8)) /* 8 of these (0-7) */
 #define	IXGBE_FCRTH(_i) (0x03260 + ((_i) * 8)) /* 8 of these (0-7) */
 #define	IXGBE_FCRTV	0x032A0
+#define	IXGBE_FCCFG	0x03D00
 #define	IXGBE_TFCS	0x0CE00
 
 /* Receive DMA Registers */
-#define	IXGBE_RDBAL(_i) (((_i) < 64) ? \
+#define	IXGBE_RDBAL(_i)		(((_i) < 64) ? \
 	(0x01000 + ((_i) * 0x40)) : (0x0D000 + ((_i - 64) * 0x40)))
-#define	IXGBE_RDBAH(_i) (((_i) < 64) ? \
+#define	IXGBE_RDBAH(_i)		(((_i) < 64) ? \
 	(0x01004 + ((_i) * 0x40)) : (0x0D004 + ((_i - 64) * 0x40)))
-#define	IXGBE_RDLEN(_i) (((_i) < 64) ? \
+#define	IXGBE_RDLEN(_i)		(((_i) < 64) ? \
 	(0x01008 + ((_i) * 0x40)) : (0x0D008 + ((_i - 64) * 0x40)))
-#define	IXGBE_RDH(_i)   (((_i) < 64) ? \
+#define	IXGBE_RDH(_i)		(((_i) < 64) ? \
 	(0x01010 + ((_i) * 0x40)) : (0x0D010 + ((_i - 64) * 0x40)))
-#define	IXGBE_RDT(_i)   (((_i) < 64) ? \
+#define	IXGBE_RDT(_i)		(((_i) < 64) ? \
 	(0x01018 + ((_i) * 0x40)) : (0x0D018 + ((_i - 64) * 0x40)))
-#define	IXGBE_RXDCTL(_i) (((_i) < 64) ? \
+#define	IXGBE_RXDCTL(_i)	(((_i) < 64) ? \
 	(0x01028 + ((_i) * 0x40)) : (0x0D028 + ((_i - 64) * 0x40)))
+#define	IXGBE_RSCCTL(_i)	(((_i) < 64) ? \
+	(0x0102C + ((_i) * 0x40)) : (0x0D02C + ((_i - 64) * 0x40)))
+#define	IXGBE_RSCDBU	0x03028
+#define	IXGBE_RDDCC	0x02F20
+#define	IXGBE_RXMEMWRAP	0x03190
+#define	IXGBE_STARCTRL	0x03024
 /*
  * Split and Replication Receive Control Registers
  * 00-15 : 0x02100 + n*4
@@ -125,6 +178,7 @@
 	(((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \
 	(0x0D00C + ((_i - 64) * 0x40))))
 #define	IXGBE_RDRXCTL    0x02F00
+#define	IXGBE_RDRXCTL_RSC_PUSH	0x80
 /* 8 of these 0x03C00 - 0x03C1C */
 #define	IXGBE_RXPBSIZE(_i)	(0x03C00 + ((_i) * 4))
 #define	IXGBE_RXCTRL	0x03000
@@ -142,6 +196,8 @@
 	(0x05400 + ((_i) * 8)) : (0x0A200 + ((_i) * 8)))
 #define	IXGBE_RAH(_i)   (((_i) <= 15) ? \
 	(0x05404 + ((_i) * 8)) : (0x0A204 + ((_i) * 8)))
+#define	IXGBE_MPSAR_LO(_i)	(0x0A600 + ((_i) * 8))
+#define	IXGBE_MPSAR_HI(_i)	(0x0A604 + ((_i) * 8))
 /* Packet split receive type */
 #define	IXGBE_PSRTYPE(_i)    (((_i) <= 15) ? \
 	(0x05480 + ((_i) * 4)) : (0x0EA00 + ((_i) * 4)))
@@ -153,6 +209,29 @@
 #define	IXGBE_VLNCTRL	0x05088
 #define	IXGBE_MCSTCTRL	0x05090
 #define	IXGBE_MRQC	0x05818
+#define	IXGBE_SAQF(_i)	(0x0E000 + ((_i) * 4)) /* Source Address Queue Filter */
+#define	IXGBE_DAQF(_i)	(0x0E200 + ((_i) * 4)) /* Dest. Address Queue Filter */
+#define	IXGBE_SDPQF(_i)	(0x0E400 + ((_i) * 4)) /* Src Dest. Addr Queue Filter */
+#define	IXGBE_FTQF(_i)	(0x0E600 + ((_i) * 4)) /* Five Tuple Queue Filter */
+#define	IXGBE_ETQF(_i)	(0x05128 + ((_i) * 4)) /* EType Queue Filter */
+#define	IXGBE_ETQS(_i)	(0x0EC00 + ((_i) * 4)) /* EType Queue Select */
+#define	IXGBE_SYNQF	0x0EC30 /* SYN Packet Queue Filter */
+#define	IXGBE_RQTC	0x0EC70
+#define	IXGBE_MTQC	0x08120
+#define	IXGBE_VLVF(_i)	(0x0F100 + ((_i) * 4))  /* 64 of these (0-63) */
+#define	IXGBE_VLVFB(_i)	(0x0F200 + ((_i) * 4))  /* 128 of these (0-127) */
+#define	IXGBE_VT_CTL	0x051B0
+#define	IXGBE_VFRE(_i)	(0x051E0 + ((_i) * 4))
+#define	IXGBE_VFTE(_i)	(0x08110 + ((_i) * 4))
+#define	IXGBE_QDE	0x2F04
+#define	IXGBE_VMOLR(_i)	(0x0F000 + ((_i) * 4)) /* 64 total */
+#define	IXGBE_UTA(_i)	(0x0F400 + ((_i) * 4))
+#define	IXGBE_VMRCTL(_i)	(0x0F600 + ((_i) * 4))
+#define	IXGBE_VMRVLAN(_i)	(0x0F610 + ((_i) * 4))
+#define	IXGBE_VMRVM(_i)		(0x0F630 + ((_i) * 4))
+#define	IXGBE_L34T_IMIR(_i)	(0x0E800 + ((_i) * 4))
+				/* 128 of these (0-127) */
+#define	IXGBE_LLITHRESH	0x0EC90
 #define	IXGBE_VMD_CTL	0x0581C
 #define	IXGBE_IMIR(_i)	(0x05A80 + ((_i) * 4))  /* 8 of these (0-7) */
 #define	IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4))  /* 8 of these (0-7) */
@@ -160,6 +239,34 @@
 #define	IXGBE_RETA(_i)	(0x05C00 + ((_i) * 4))  /* 32 of these (0-31) */
 #define	IXGBE_RSSRK(_i)	(0x05C80 + ((_i) * 4))  /* 10 of these (0-9) */
 
+/* Flow Director registers */
+#define	IXGBE_FDIRCTRL	0x0EE00
+#define	IXGBE_FDIRHKEY	0x0EE68
+#define	IXGBE_FDIRSKEY	0x0EE6C
+#define	IXGBE_FDIRDIP4M	0x0EE3C
+#define	IXGBE_FDIRSIP4M	0x0EE40
+#define	IXGBE_FDIRTCPM	0x0EE44
+#define	IXGBE_FDIRUDPM	0x0EE48
+#define	IXGBE_FDIRIP6M	0x0EE74
+#define	IXGBE_FDIRM	0x0EE70
+
+/* Flow Director Stats registers */
+#define	IXGBE_FDIRFREE	0x0EE38
+#define	IXGBE_FDIRLEN	0x0EE4C
+#define	IXGBE_FDIRUSTAT	0x0EE50
+#define	IXGBE_FDIRFSTAT	0x0EE54
+#define	IXGBE_FDIRMATCH	0x0EE58
+#define	IXGBE_FDIRMISS	0x0EE5C
+
+/* Flow Director Programming registers */
+#define	IXGBE_FDIRSIPv6(_i)	(0x0EE0C + ((_i) * 4)) /* 3 of these (0-2) */
+#define	IXGBE_FDIRIPSA	0x0EE18
+#define	IXGBE_FDIRIPDA	0x0EE1C
+#define	IXGBE_FDIRPORT	0x0EE20
+#define	IXGBE_FDIRVLAN	0x0EE24
+#define	IXGBE_FDIRHASH	0x0EE28
+#define	IXGBE_FDIRCMD	0x0EE2C
+
 /* Transmit DMA registers */
 #define	IXGBE_TDBAL(_i)	(0x06000 + ((_i) * 0x40)) /* 32 of these (0-31) */
 #define	IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
@@ -171,12 +278,25 @@
 #define	IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
 #define	IXGBE_DTXCTL	0x07E00
 
+#define	IXGBE_DMATXCTL		0x04A80
+#define	IXGBE_DTXMXSZRQ		0x08100
+#define	IXGBE_DTXTCPFLGL	0x04A88
+#define	IXGBE_DTXTCPFLGH	0x04A8C
+#define	IXGBE_LBDRPEN		0x0CA00
+#define	IXGBE_TXPBTHRESH(_i)	(0x04950 + ((_i) * 4)) /* 8 of these 0 - 7 */
+
+#define	IXGBE_DMATXCTL_TE	0x1 /* Transmit Enable */
+#define	IXGBE_DMATXCTL_NS	0x2 /* No Snoop LSO hdr buffer */
+#define	IXGBE_DMATXCTL_GDV	0x8 /* Global Double VLAN */
+#define	IXGBE_DMATXCTL_VT_SHIFT	16  /* VLAN EtherType */
 #define	IXGBE_DCA_TXCTRL(_i)	(0x07200 + ((_i) * 4)) /* 16 of these (0-15) */
+/* Tx DCA Control register : 128 of these (0-127) */
+#define	IXGBE_DCA_TXCTRL_82599(_i)	(0x0600C + ((_i) * 0x40))
 #define	IXGBE_TIPG		0x0CB00
 #define	IXGBE_TXPBSIZE(_i)	(0x0CC00 + ((_i) *0x04)) /* 8 of these */
 #define	IXGBE_MNGTXMAP		0x0CD10
-#define	IXGBE_TIPG_FIBER_DEFAULT 3
-#define	IXGBE_TXPBSIZE_SHIFT	10
+#define	IXGBE_TIPG_FIBER_DEFAULT	3
+#define	IXGBE_TXPBSIZE_SHIFT		10
 
 /* Wake up registers */
 #define	IXGBE_WUC	0x05800
@@ -187,9 +307,68 @@
 #define	IXGBE_IP6AT	0x05880 /* IPv6 table 0x5880-0x588F */
 #define	IXGBE_WUPL	0x05900
 #define	IXGBE_WUPM	0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
-#define	IXGBE_FHFT	0x09000 /* Flex host filter table 9000-93FC */
+#define	IXGBE_FHFT(_n)	(0x09000 + (_n * 0x100)) /* Flex host filter table */
+/* Ext Flexible Host Filter Table */
+#define	IXGBE_FHFT_EXT(_n)	(0x09800 + (_n * 0x100))
+#define	IXGBE_FLEXIBLE_FILTER_COUNT_MAX		4
+#define	IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX	2
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define	IXGBE_FLEXIBLE_FILTER_SIZE_MAX	128
+#define	IXGBE_FHFT_LENGTH_OFFSET	0xFC  /* Length byte in FHFT */
+#define	IXGBE_FHFT_LENGTH_MASK		0x0FF /* Length in lower byte */
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define	IXGBE_WUC_PME_EN	0x00000002 /* PME Enable */
+#define	IXGBE_WUC_PME_STATUS	0x00000004 /* PME Status */
+#define	IXGBE_WUC_ADVD3WUC	0x00000010 /* D3Cold wake up cap. enable */
+
+/* Wake Up Filter Control */
+#define	IXGBE_WUFC_LNKC	0x00000001 /* Link Status Change Wakeup Enable */
+#define	IXGBE_WUFC_MAG	0x00000002 /* Magic Packet Wakeup Enable */
+#define	IXGBE_WUFC_EX	0x00000004 /* Directed Exact Wakeup Enable */
+#define	IXGBE_WUFC_MC	0x00000008 /* Directed Multicast Wakeup Enable */
+#define	IXGBE_WUFC_BC	0x00000010 /* Broadcast Wakeup Enable */
+#define	IXGBE_WUFC_ARP	0x00000020 /* ARP Request Packet Wakeup Enable */
+#define	IXGBE_WUFC_IPV4	0x00000040 /* Directed IPv4 Packet Wakeup Enable */
+#define	IXGBE_WUFC_IPV6	0x00000080 /* Directed IPv6 Packet Wakeup Enable */
+#define	IXGBE_WUFC_MNG	0x00000100 /* Directed Mgmt Packet Wakeup Enable */
 
-/* Music registers */
+#define	IXGBE_WUFC_IGNORE_TCO	0x00008000 /* Ignore WakeOn TCO packets */
+#define	IXGBE_WUFC_FLX0		0x00010000 /* Flexible Filter 0 Enable */
+#define	IXGBE_WUFC_FLX1		0x00020000 /* Flexible Filter 1 Enable */
+#define	IXGBE_WUFC_FLX2		0x00040000 /* Flexible Filter 2 Enable */
+#define	IXGBE_WUFC_FLX3		0x00080000 /* Flexible Filter 3 Enable */
+#define	IXGBE_WUFC_FLX4		0x00100000 /* Flexible Filter 4 Enable */
+#define	IXGBE_WUFC_FLX5		0x00200000 /* Flexible Filter 5 Enable */
+#define	IXGBE_WUFC_FLX_FILTERS	0x000F0000 /* Mask for 4 flex filters */
+#define	IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 /* Mask for Ext. flex filters */
+#define	IXGBE_WUFC_ALL_FILTERS	0x003F00FF /* Mask for all 6 wakeup filters */
+#define	IXGBE_WUFC_FLX_OFFSET	16 /* Offset to the Flexible Filters bits */
+
+/* Wake Up Status */
+#define	IXGBE_WUS_LNKC	IXGBE_WUFC_LNKC
+#define	IXGBE_WUS_MAG	IXGBE_WUFC_MAG
+#define	IXGBE_WUS_EX	IXGBE_WUFC_EX
+#define	IXGBE_WUS_MC	IXGBE_WUFC_MC
+#define	IXGBE_WUS_BC	IXGBE_WUFC_BC
+#define	IXGBE_WUS_ARP	IXGBE_WUFC_ARP
+#define	IXGBE_WUS_IPV4	IXGBE_WUFC_IPV4
+#define	IXGBE_WUS_IPV6	IXGBE_WUFC_IPV6
+#define	IXGBE_WUS_MNG	IXGBE_WUFC_MNG
+#define	IXGBE_WUS_FLX0	IXGBE_WUFC_FLX0
+#define	IXGBE_WUS_FLX1	IXGBE_WUFC_FLX1
+#define	IXGBE_WUS_FLX2	IXGBE_WUFC_FLX2
+#define	IXGBE_WUS_FLX3	IXGBE_WUFC_FLX3
+#define	IXGBE_WUS_FLX4	IXGBE_WUFC_FLX4
+#define	IXGBE_WUS_FLX5	IXGBE_WUFC_FLX5
+#define	IXGBE_WUS_FLX_FILTERS	IXGBE_WUFC_FLX_FILTERS
+
+/* Wake Up Packet Length */
+#define	IXGBE_WUPL_LENGTH_MASK	0xFFFF
+
+/* DCB registers */
 #define	IXGBE_RMCS	0x03D00
 #define	IXGBE_DPMCS	0x07F40
 #define	IXGBE_PDPMCS	0x0CD00
@@ -201,6 +380,179 @@
 #define	IXGBE_TDPT2TCCR(_i)	(0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
 #define	IXGBE_TDPT2TCSR(_i)	(0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
 
+/* Security Control Registers */
+#define	IXGBE_SECTXCTRL		0x08800
+#define	IXGBE_SECTXSTAT		0x08804
+#define	IXGBE_SECTXBUFFAF	0x08808
+#define	IXGBE_SECTXMINIFG	0x08810
+#define	IXGBE_SECTXSTAT		0x08804
+#define	IXGBE_SECRXCTRL		0x08D00
+#define	IXGBE_SECRXSTAT		0x08D04
+
+/* Security Bit Fields and Masks */
+#define	IXGBE_SECTXCTRL_SECTX_DIS	0x00000001
+#define	IXGBE_SECTXCTRL_TX_DIS		0x00000002
+#define	IXGBE_SECTXCTRL_STORE_FORWARD	0x00000004
+
+#define	IXGBE_SECTXSTAT_SECTX_RDY	0x00000001
+#define	IXGBE_SECTXSTAT_ECC_TXERR	0x00000002
+
+#define	IXGBE_SECRXCTRL_SECRX_DIS	0x00000001
+#define	IXGBE_SECRXCTRL_RX_DIS		0x00000002
+
+#define	IXGBE_SECRXSTAT_SECRX_RDY	0x00000001
+#define	IXGBE_SECRXSTAT_ECC_RXERR	0x00000002
+
+/* LinkSec (MacSec) Registers */
+#define	IXGBE_LSECTXCAP		0x08A00
+#define	IXGBE_LSECRXCAP		0x08F00
+#define	IXGBE_LSECTXCTRL	0x08A04
+#define	IXGBE_LSECTXSCL		0x08A08 /* SCI Low */
+#define	IXGBE_LSECTXSCH		0x08A0C /* SCI High */
+#define	IXGBE_LSECTXSA		0x08A10
+#define	IXGBE_LSECTXPN0		0x08A14
+#define	IXGBE_LSECTXPN1		0x08A18
+#define	IXGBE_LSECTXKEY0(_n)	(0x08A1C + (4 * (_n))) /* 4 of these (0-3) */
+#define	IXGBE_LSECTXKEY1(_n)	(0x08A2C + (4 * (_n))) /* 4 of these (0-3) */
+#define	IXGBE_LSECRXCTRL	0x08F04
+#define	IXGBE_LSECRXSCL		0x08F08
+#define	IXGBE_LSECRXSCH		0x08F0C
+#define	IXGBE_LSECRXSA(_i)	(0x08F10 + (4 * (_i))) /* 2 of these (0-1) */
+#define	IXGBE_LSECRXPN(_i)	(0x08F18 + (4 * (_i))) /* 2 of these (0-1) */
+#define	IXGBE_LSECRXKEY(_n, _m)	(0x08F20 + ((0x10 * (_n)) + (4 * (_m))))
+#define	IXGBE_LSECTXUT		0x08A3C /* OutPktsUntagged */
+#define	IXGBE_LSECTXPKTE	0x08A40 /* OutPktsEncrypted */
+#define	IXGBE_LSECTXPKTP	0x08A44 /* OutPktsProtected */
+#define	IXGBE_LSECTXOCTE	0x08A48 /* OutOctetsEncrypted */
+#define	IXGBE_LSECTXOCTP	0x08A4C /* OutOctetsProtected */
+#define	IXGBE_LSECRXUT		0x08F40 /* InPktsUntagged/InPktsNoTag */
+#define	IXGBE_LSECRXOCTD	0x08F44 /* InOctetsDecrypted */
+#define	IXGBE_LSECRXOCTV	0x08F48 /* InOctetsValidated */
+#define	IXGBE_LSECRXBAD		0x08F4C /* InPktsBadTag */
+#define	IXGBE_LSECRXNOSCI	0x08F50 /* InPktsNoSci */
+#define	IXGBE_LSECRXUNSCI	0x08F54 /* InPktsUnknownSci */
+#define	IXGBE_LSECRXUNCH	0x08F58 /* InPktsUnchecked */
+#define	IXGBE_LSECRXDELAY	0x08F5C /* InPktsDelayed */
+#define	IXGBE_LSECRXLATE	0x08F60 /* InPktsLate */
+#define	IXGBE_LSECRXOK(_n)	(0x08F64 + (0x04 * (_n))) /* InPktsOk */
+#define	IXGBE_LSECRXINV(_n)	(0x08F6C + (0x04 * (_n))) /* InPktsInvalid */
+#define	IXGBE_LSECRXNV(_n)	(0x08F74 + (0x04 * (_n))) /* InPktsNotValid */
+#define	IXGBE_LSECRXUNSA	0x08F7C /* InPktsUnusedSa */
+#define	IXGBE_LSECRXNUSA	0x08F80 /* InPktsNotUsingSa */
+
+/* LinkSec (MacSec) Bit Fields and Masks */
+#define	IXGBE_LSECTXCAP_SUM_MASK	0x00FF0000
+#define	IXGBE_LSECTXCAP_SUM_SHIFT	16
+#define	IXGBE_LSECRXCAP_SUM_MASK	0x00FF0000
+#define	IXGBE_LSECRXCAP_SUM_SHIFT	16
+
+#define	IXGBE_LSECTXCTRL_EN_MASK	0x00000003
+#define	IXGBE_LSECTXCTRL_DISABLE	0x0
+#define	IXGBE_LSECTXCTRL_AUTH		0x1
+#define	IXGBE_LSECTXCTRL_AUTH_ENCRYPT	0x2
+#define	IXGBE_LSECTXCTRL_AISCI		0x00000020
+#define	IXGBE_LSECTXCTRL_PNTHRSH_MASK	0xFFFFFF00
+#define	IXGBE_LSECTXCTRL_RSV_MASK	0x000000D8
+
+#define	IXGBE_LSECRXCTRL_EN_MASK	0x0000000C
+#define	IXGBE_LSECRXCTRL_EN_SHIFT	2
+#define	IXGBE_LSECRXCTRL_DISABLE	0x0
+#define	IXGBE_LSECRXCTRL_CHECK		0x1
+#define	IXGBE_LSECRXCTRL_STRICT		0x2
+#define	IXGBE_LSECRXCTRL_DROP		0x3
+#define	IXGBE_LSECRXCTRL_PLSH		0x00000040
+#define	IXGBE_LSECRXCTRL_RP		0x00000080
+#define	IXGBE_LSECRXCTRL_RSV_MASK	0xFFFFFF33
+
+/* IpSec Registers */
+#define	IXGBE_IPSTXIDX		0x08900
+#define	IXGBE_IPSTXSALT		0x08904
+#define	IXGBE_IPSTXKEY(_i)	(0x08908 + (4 * (_i))) /* 4 of these (0-3) */
+#define	IXGBE_IPSRXIDX		0x08E00
+#define	IXGBE_IPSRXIPADDR(_i)	(0x08E04 + (4 * (_i))) /* 4 of these (0-3) */
+#define	IXGBE_IPSRXSPI		0x08E14
+#define	IXGBE_IPSRXIPIDX	0x08E18
+#define	IXGBE_IPSRXKEY(_i)	(0x08E1C + (4 * (_i))) /* 4 of these (0-3) */
+#define	IXGBE_IPSRXSALT		0x08E2C
+#define	IXGBE_IPSRXMOD		0x08E30
+
+#define	IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE	0x4
+
+/* DCB registers */
+#define	IXGBE_RTRPCS		0x02430
+#define	IXGBE_RTTDCS		0x04900
+#define	IXGBE_RTTPCS		0x0CD00
+#define	IXGBE_RTRUP2TC		0x03020
+#define	IXGBE_RTTUP2TC		0x0C800
+#define	IXGBE_RTRPT4C(_i)	(0x02140 + ((_i) * 4)) /* 8 of these (0-7) */
+#define	IXGBE_RTRPT4S(_i)	(0x02160 + ((_i) * 4)) /* 8 of these (0-7) */
+#define	IXGBE_RTTDT2C(_i)	(0x04910 + ((_i) * 4)) /* 8 of these (0-7) */
+#define	IXGBE_RTTDT2S(_i)	(0x04930 + ((_i) * 4)) /* 8 of these (0-7) */
+#define	IXGBE_RTTPT2C(_i)	(0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
+#define	IXGBE_RTTPT2S(_i)	(0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
+#define	IXGBE_RTTDQSEL		0x04904
+#define	IXGBE_RTTDT1C		0x04908
+#define	IXGBE_RTTDT1S		0x0490C
+#define	IXGBE_RTTDTECC		0x04990
+#define	IXGBE_RTTDTECC_NO_BCN	0x00000100
+
+#define	IXGBE_RTTBCNRC		0x04984
+
+/* FCoE DMA Context Registers */
+#define	IXGBE_FCPTRL	0x02410 /* FC User Desc. PTR Low */
+#define	IXGBE_FCPTRH	0x02414 /* FC USer Desc. PTR High */
+#define	IXGBE_FCBUFF	0x02418 /* FC Buffer Control */
+#define	IXGBE_FCDMARW	0x02420 /* FC Receive DMA RW */
+#define	IXGBE_FCINVST0	0x03FC0 /* FC Invalid DMA Context Status Reg 0 */
+#define	IXGBE_FCINVST(_i)	(IXGBE_FCINVST0 + ((_i) * 4))
+#define	IXGBE_FCBUFF_VALID	(1 << 0)   /* DMA Context Valid */
+#define	IXGBE_FCBUFF_BUFFSIZE	(3 << 3)   /* User Buffer Size */
+#define	IXGBE_FCBUFF_WRCONTX	(1 << 7)   /* 0: Initiator, 1: Target */
+#define	IXGBE_FCBUFF_BUFFCNT	0x0000ff00 /* Number of User Buffers */
+#define	IXGBE_FCBUFF_OFFSET	0xffff0000 /* User Buffer Offset */
+#define	IXGBE_FCBUFF_BUFFSIZE_SHIFT	3
+#define	IXGBE_FCBUFF_BUFFCNT_SHIFT	8
+#define	IXGBE_FCBUFF_OFFSET_SHIFT	16
+#define	IXGBE_FCDMARW_WE	(1 << 14)   /* Write enable */
+#define	IXGBE_FCDMARW_RE	(1 << 15)   /* Read enable */
+#define	IXGBE_FCDMARW_FCOESEL	0x000001ff  /* FC X_ID: 11 bits */
+#define	IXGBE_FCDMARW_LASTSIZE	0xffff0000  /* Last User Buffer Size */
+#define	IXGBE_FCDMARW_LASTSIZE_SHIFT	16
+/* FCoE SOF/EOF */
+#define	IXGBE_TEOFF	0x04A94 /* Tx FC EOF */
+#define	IXGBE_TSOFF	0x04A98 /* Tx FC SOF */
+#define	IXGBE_REOFF	0x05158 /* Rx FC EOF */
+#define	IXGBE_RSOFF	0x051F8 /* Rx FC SOF */
+/* FCoE Filter Context Registers */
+#define	IXGBE_FCFLT	0x05108 /* FC FLT Context */
+#define	IXGBE_FCFLTRW	0x05110 /* FC Filter RW Control */
+#define	IXGBE_FCPARAM	0x051d8 /* FC Offset Parameter */
+#define	IXGBE_FCFLT_VALID	(1 << 0)   /* Filter Context Valid */
+#define	IXGBE_FCFLT_FIRST	(1 << 1)   /* Filter First */
+#define	IXGBE_FCFLT_SEQID	0x00ff0000 /* Sequence ID */
+#define	IXGBE_FCFLT_SEQCNT	0xff000000 /* Sequence Count */
+#define	IXGBE_FCFLTRW_RVALDT	(1 << 13)  /* Fast Re-Validation */
+#define	IXGBE_FCFLTRW_WE	(1 << 14)  /* Write Enable */
+#define	IXGBE_FCFLTRW_RE	(1 << 15)  /* Read Enable */
+/* FCoE Receive Control */
+#define	IXGBE_FCRXCTRL		0x05100 /* FC Receive Control */
+#define	IXGBE_FCRXCTRL_FCOELLI	(1 << 0)   /* Low latency interrupt */
+#define	IXGBE_FCRXCTRL_SAVBAD	(1 << 1)   /* Save Bad Frames */
+#define	IXGBE_FCRXCTRL_FRSTRDH	(1 << 2)   /* EN 1st Read Header */
+#define	IXGBE_FCRXCTRL_LASTSEQH	(1 << 3)   /* EN Last Header in Seq */
+#define	IXGBE_FCRXCTRL_ALLH	(1 << 4)   /* EN All Headers */
+#define	IXGBE_FCRXCTRL_FRSTSEQH	(1 << 5)   /* EN 1st Seq. Header */
+#define	IXGBE_FCRXCTRL_ICRC	(1 << 6)   /* Ignore Bad FC CRC */
+#define	IXGBE_FCRXCTRL_FCCRCBO	(1 << 7)   /* FC CRC Byte Ordering */
+#define	IXGBE_FCRXCTRL_FCOEVER	0x00000f00 /* FCoE Version: 4 bits */
+#define	IXGBE_FCRXCTRL_FCOEVER_SHIFT	8
+/* FCoE Redirection */
+#define	IXGBE_FCRECTL		0x0ED00 /* FC Redirection Control */
+#define	IXGBE_FCRETA0		0x0ED10 /* FC Redirection Table 0 */
+#define	IXGBE_FCRETA(_i)	(IXGBE_FCRETA0 + ((_i) * 4)) /* FCoE Redir */
+#define	IXGBE_FCRECTL_ENA	0x1	/* FCoE Redir Table Enable */
+#define	IXGBE_FCRETA_SIZE	8	/* Max entries in FCRETA */
+#define	IXGBE_FCRETA_ENTRY_MASK	0x0000007f /* 7 bits for the queue index */
 
 /* Stats registers */
 #define	IXGBE_CRCERRS	0x04000
@@ -215,6 +567,11 @@
 #define	IXGBE_LXONRXC	0x0CF60
 #define	IXGBE_LXOFFTXC	0x03F68
 #define	IXGBE_LXOFFRXC	0x0CF68
+#define	IXGBE_LXONRXCNT	0x041A4
+#define	IXGBE_LXOFFRXCNT	0x041A8
+#define	IXGBE_PXONRXCNT(_i)	(0x04140 + ((_i) * 4)) /* 8 of these */
+#define	IXGBE_PXOFFRXCNT(_i)	(0x04160 + ((_i) * 4)) /* 8 of these */
+#define	IXGBE_PXON2OFFCNT(_i)	(0x03240 + ((_i) * 4)) /* 8 of these */
 #define	IXGBE_PXONTXC(_i) (0x03F00 + ((_i) * 4)) /* 8 of these 3F00-3F1C */
 #define	IXGBE_PXONRXC(_i) (0x0CF00 + ((_i) * 4)) /* 8 of these CF00-CF1C */
 #define	IXGBE_PXOFFTXC(_i) (0x03F20 + ((_i) * 4)) /* 8 of these 3F20-3F3C */
@@ -254,15 +611,29 @@
 #define	IXGBE_MPTC	0x040F0
 #define	IXGBE_BPTC	0x040F4
 #define	IXGBE_XEC	0x04120
+#define	IXGBE_SSVPC	0x08780
 
-#define	IXGBE_RQSMR(_i)	(0x02300 + ((_i) * 4)) /* 16 of these */
+#define	IXGBE_RQSMR(_i)	(0x02300 + ((_i) * 4))
 #define	IXGBE_TQSMR(_i)	(((_i) <= 7) ? \
 	(0x07300 + ((_i) * 4)) : (0x08600 + ((_i) * 4)))
+#define	IXGBE_TQSM(_i)	(0x08600 + ((_i) * 4))
 
 #define	IXGBE_QPRC(_i)	(0x01030 + ((_i) * 0x40)) /* 16 of these */
 #define	IXGBE_QPTC(_i)	(0x06030 + ((_i) * 0x40)) /* 16 of these */
 #define	IXGBE_QBRC(_i)	(0x01034 + ((_i) * 0x40)) /* 16 of these */
 #define	IXGBE_QBTC(_i)	(0x06034 + ((_i) * 0x40)) /* 16 of these */
+#define	IXGBE_QPRDC(_i)	(0x01430 + ((_i) * 0x40)) /* 16 of these */
+#define	IXGBE_QBTC_L(_i)	(0x08700 + ((_i) * 0x8)) /* 16 of these */
+#define	IXGBE_QBTC_H(_i)	(0x08704 + ((_i) * 0x8)) /* 16 of these */
+#define	IXGBE_FCCRC	0x05118 /* Count of Good Eth CRC w/ Bad FC CRC */
+#define	IXGBE_FCOERPDC	0x0241C /* FCoE Rx Packets Dropped Count */
+#define	IXGBE_FCLAST	0x02424 /* FCoE Last Error Count */
+#define	IXGBE_FCOEPRC	0x02428 /* Number of FCoE Packets Received */
+#define	IXGBE_FCOEDWRC	0x0242C /* Number of FCoE DWords Received */
+#define	IXGBE_FCOEPTC	0x08784 /* Number of FCoE Packets Transmitted */
+#define	IXGBE_FCOEDWTC	0x08788 /* Number of FCoE DWords Transmitted */
+#define	IXGBE_FCCRC_CNT_MASK	0x0000FFFF /* CRC_CNT: bit 0 - 15 */
+#define	IXGBE_FCLAST_CNT_MASK	0x0000FFFF /* Last_CNT: bit 0 - 15 */
 
 /* Management */
 #define	IXGBE_MAVTV(_i)	(0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
@@ -275,6 +646,9 @@
 #define	IXGBE_MMAL(_i)	(0x05910 + ((_i) * 8)) /* 4 of these (0-3) */
 #define	IXGBE_MMAH(_i)	(0x05914 + ((_i) * 8)) /* 4 of these (0-3) */
 #define	IXGBE_FTFT	0x09400 /* 0x9400-0x97FC */
+#define	IXGBE_METF(_i)	(0x05190 + ((_i) * 4)) /* 4 of these (0-3) */
+#define	IXGBE_MDEF_EXT(_i)	(0x05160 + ((_i) * 4)) /* 8 of these (0-7) */
+#define	IXGBE_LSWFW	0x15014
 
 /* ARC Subsystem registers */
 #define	IXGBE_HICR	0x15F00
@@ -307,16 +681,65 @@
 #define	IXGBE_DCA_ID	0x11070
 #define	IXGBE_DCA_CTRL	0x11074
 
+/* PCI-E registers 82599 Specific */
+#define	IXGBE_GCR_EXT		0x11050
+#define	IXGBE_GSCL_5_82599	0x11030
+#define	IXGBE_GSCL_6_82599	0x11034
+#define	IXGBE_GSCL_7_82599	0x11038
+#define	IXGBE_GSCL_8_82599	0x1103C
+#define	IXGBE_PHYADR_82599	0x11040
+#define	IXGBE_PHYDAT_82599	0x11044
+#define	IXGBE_PHYCTL_82599	0x11048
+#define	IXGBE_PBACLR_82599	0x11068
+#define	IXGBE_CIAA_82599	0x11088
+#define	IXGBE_CIAD_82599	0x1108C
+#define	IXGBE_PCIE_DIAG_0_82599	0x11090
+#define	IXGBE_PCIE_DIAG_1_82599	0x11094
+#define	IXGBE_PCIE_DIAG_2_82599	0x11098
+#define	IXGBE_PCIE_DIAG_3_82599	0x1109C
+#define	IXGBE_PCIE_DIAG_4_82599	0x110A0
+#define	IXGBE_PCIE_DIAG_5_82599	0x110A4
+#define	IXGBE_PCIE_DIAG_6_82599	0x110A8
+#define	IXGBE_PCIE_DIAG_7_82599	0x110C0
+#define	IXGBE_INTRPT_CSR_82599	0x110B0
+#define	IXGBE_INTRPT_MASK_82599	0x110B8
+#define	IXGBE_CDQ_MBR_82599	0x110B4
+#define	IXGBE_MISC_REG_82599	0x110F0
+#define	IXGBE_ECC_CTRL_0_82599	0x11100
+#define	IXGBE_ECC_CTRL_1_82599	0x11104
+#define	IXGBE_ECC_STATUS_82599	0x110E0
+#define	IXGBE_BAR_CTRL_82599	0x110F4
+
+/* Time Sync Registers */
+#define	IXGBE_TSYNCRXCTL	0x05188 /* Rx Time Sync Control register - RW */
+#define	IXGBE_TSYNCTXCTL	0x08C00 /* Tx Time Sync Control register - RW */
+#define	IXGBE_RXSTMPL	0x051E8 /* Rx timestamp Low - RO */
+#define	IXGBE_RXSTMPH	0x051A4 /* Rx timestamp High - RO */
+#define	IXGBE_RXSATRL	0x051A0 /* Rx timestamp attribute low - RO */
+#define	IXGBE_RXSATRH	0x051A8 /* Rx timestamp attribute high - RO */
+#define	IXGBE_RXMTRL	0x05120 /* RX message type register low - RW */
+#define	IXGBE_TXSTMPL	0x08C04 /* Tx timestamp value Low - RO */
+#define	IXGBE_TXSTMPH	0x08C08 /* Tx timestamp value High - RO */
+#define	IXGBE_SYSTIML	0x08C0C /* System time register Low - RO */
+#define	IXGBE_SYSTIMH	0x08C10 /* System time register High - RO */
+#define	IXGBE_TIMINCA	0x08C14 /* Increment attributes register - RW */
+#define	IXGBE_RXUDP	0x08C1C /* Time Sync Rx UDP Port - RW */
+
 /* Diagnostic Registers */
 #define	IXGBE_RDSTATCTL		0x02C20
 #define	IXGBE_RDSTAT(_i)	(0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
 #define	IXGBE_RDHMPN		0x02F08
 #define	IXGBE_RIC_DW(_i)	(0x02F10 + ((_i) * 4))
 #define	IXGBE_RDPROBE		0x02F20
+#define	IXGBE_RDMAM		0x02F30
+#define	IXGBE_RDMAD		0x02F34
 #define	IXGBE_TDSTATCTL		0x07C20
 #define	IXGBE_TDSTAT(_i)	(0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
 #define	IXGBE_TDHMPN		0x07F08
+#define	IXGBE_TDHMPN2		0x082FC
+#define	IXGBE_TXDESCIC		0x082CC
 #define	IXGBE_TIC_DW(_i)	(0x07F10 + ((_i) * 4))
+#define	IXGBE_TIC_DW2(_i)	(0x082B0 + ((_i) * 4))
 #define	IXGBE_TDPROBE		0x07F20
 #define	IXGBE_TXBUFCTRL		0x0C600
 #define	IXGBE_TXBUFDATA0	0x0C610
@@ -344,6 +767,10 @@
 #define	IXGBE_TXDATARDPTR(_i) (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C */
 #define	IXGBE_TXDESCRDPTR(_i) (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C */
 #define	IXGBE_PCIEECCCTL	0x1106C
+#define	IXGBE_PCIEECCCTL0	0x11100
+#define	IXGBE_PCIEECCCTL1	0x11104
+#define	IXGBE_RXDBUECC		0x03F70
+#define	IXGBE_TXDBUECC		0x0CF70
 #define	IXGBE_PBTXECC		0x0C300
 #define	IXGBE_PBRXECC		0x03300
 #define	IXGBE_GHECCR		0x110B0
@@ -369,24 +796,74 @@
 #define	IXGBE_MSRWD		0x04260
 #define	IXGBE_MLADD		0x04264
 #define	IXGBE_MHADD		0x04268
+#define	IXGBE_MAXFRS		0x04268
 #define	IXGBE_TREG		0x0426C
 #define	IXGBE_PCSS1		0x04288
 #define	IXGBE_PCSS2		0x0428C
 #define	IXGBE_XPCSS		0x04290
+#define	IXGBE_MFLCN		0x04294
 #define	IXGBE_SERDESC		0x04298
 #define	IXGBE_MACS		0x0429C
 #define	IXGBE_AUTOC		0x042A0
 #define	IXGBE_LINKS		0x042A4
+#define	IXGBE_LINKS2		0x04324
 #define	IXGBE_AUTOC2		0x042A8
 #define	IXGBE_AUTOC3		0x042AC
 #define	IXGBE_ANLP1		0x042B0
 #define	IXGBE_ANLP2		0x042B4
 #define	IXGBE_ATLASCTL		0x04800
+#define	IXGBE_MMNGC		0x042D0
+#define	IXGBE_ANLPNP1		0x042D4
+#define	IXGBE_ANLPNP2		0x042D8
+#define	IXGBE_KRPCSFC		0x042E0
+#define	IXGBE_KRPCSS		0x042E4
+#define	IXGBE_FECS1		0x042E8
+#define	IXGBE_FECS2		0x042EC
+#define	IXGBE_SMADARCTL		0x14F10
+#define	IXGBE_MPVC		0x04318
+#define	IXGBE_SGMIIC		0x04314
+
+/* Omer CORECTL */
+#define	IXGBE_CORECTL		0x014F00
+/* BARCTRL */
+#define	IXGBE_BARCTRL		0x110F4
+#define	IXGBE_BARCTRL_FLSIZE	0x0700
+#define	IXGBE_BARCTRL_CSRSIZE	0x2000
+
+/* RSCCTL Bit Masks */
+#define	IXGBE_RSCCTL_RSCEN	0x01
+#define	IXGBE_RSCCTL_MAXDESC_1	0x00
+#define	IXGBE_RSCCTL_MAXDESC_4	0x04
+#define	IXGBE_RSCCTL_MAXDESC_8	0x08
+#define	IXGBE_RSCCTL_MAXDESC_16	0x0C
+
+/* RSCDBU Bit Masks */
+#define	IXGBE_RSCDBU_RSCSMALDIS_MASK	0x0000007F
+#define	IXGBE_RSCDBU_RSCACKDIS		0x00000080
 
 /* RDRXCTL Bit Masks */
 #define	IXGBE_RDRXCTL_RDMTS_1_2	0x00000000 /* Rx Desc Min Threshold Size */
+#define	IXGBE_RDRXCTL_CRCSTRIP	0x00000002 /* CRC Strip */
 #define	IXGBE_RDRXCTL_MVMEN	0x00000020
 #define	IXGBE_RDRXCTL_DMAIDONE	0x00000008 /* DMA init cycle done */
+#define	IXGBE_RDRXCTL_AGGDIS	0x00010000 /* Aggregation disable */
+#define	IXGBE_RDRXCTL_RSCFRSTSIZE	0x003E0000 /* RSC First packet size */
+#define	IXGBE_RDRXCTL_RSCLLIDIS	0x00800000 /* Disable RSC compl on LLI */
+
+/* RQTC Bit Masks and Shifts */
+#define	IXGBE_RQTC_SHIFT_TC(_i)	((_i) * 4)
+#define	IXGBE_RQTC_TC0_MASK	(0x7 << 0)
+#define	IXGBE_RQTC_TC1_MASK	(0x7 << 4)
+#define	IXGBE_RQTC_TC2_MASK	(0x7 << 8)
+#define	IXGBE_RQTC_TC3_MASK	(0x7 << 12)
+#define	IXGBE_RQTC_TC4_MASK	(0x7 << 16)
+#define	IXGBE_RQTC_TC5_MASK	(0x7 << 20)
+#define	IXGBE_RQTC_TC6_MASK	(0x7 << 24)
+#define	IXGBE_RQTC_TC7_MASK	(0x7 << 28)
+
+/* PSRTYPE.RQPL Bit masks and shift */
+#define	IXGBE_PSRTYPE_RQPL_MASK		0x7
+#define	IXGBE_PSRTYPE_RQPL_SHIFT	29
 
 /* CTRL Bit Masks */
 #define	IXGBE_CTRL_GIO_DIS	0x00000004 /* Global IO Master Disable bit */
@@ -414,11 +891,18 @@
 #define	IXGBE_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
 
 #define	IXGBE_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
+#define	IXGBE_DCA_RXCTRL_CPUID_MASK_82599 0xFF000000 /* Rx CPUID Mask */
+#define	IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599 24 /* Rx CPUID Shift */
 #define	IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
 #define	IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
 #define	IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
+#define	IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx rd Desc Relax Order */
+#define	IXGBE_DCA_RXCTRL_DESC_WRO_EN (1 << 13) /* DCA Rx wr Desc Relax Order */
+#define	IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */
 
 #define	IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
+#define	IXGBE_DCA_TXCTRL_CPUID_MASK_82599  0xFF000000 /* Tx CPUID Mask */
+#define	IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599 24 /* Tx CPUID Shift */
 #define	IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
 #define	IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
 #define	IXGBE_DCA_MAX_QUEUES_82598   16 /* DCA regs only on 16 queues */
@@ -467,6 +951,9 @@
 #define	IXGBE_ATLAS_PDN_TX_1G_QL_ALL	0xF0
 #define	IXGBE_ATLAS_PDN_TX_AN_QL_ALL	0xF0
 
+/* Omer bit masks */
+#define	IXGBE_CORECTL_WRITE_CMD		0x00010000
+
 /* Device Type definitions for new protocol MDIO commands */
 #define	IXGBE_MDIO_PMA_PMD_DEV_TYPE		0x1
 #define	IXGBE_MDIO_PCS_DEV_TYPE			0x3
@@ -493,8 +980,13 @@
 #define	IXGBE_MDIO_PHY_SPEED_ABILITY	0x4 /* Speed Ability Reg */
 #define	IXGBE_MDIO_PHY_SPEED_10G	0x0001 /* 10G capable */
 #define	IXGBE_MDIO_PHY_SPEED_1G		0x0010 /* 1G capable */
+#define	IXGBE_MDIO_PHY_EXT_ABILITY	0xB /* Ext Ability Reg */
+#define	IXGBE_MDIO_PHY_10GBASET_ABILITY	0x0004 /* 10GBaseT capable */
+#define	IXGBE_MDIO_PHY_1000BASET_ABILITY	0x0020 /* 1000BaseT capable */
+#define	IXGBE_MDIO_PHY_100BASETX_ABILITY	0x0080 /* 100BaseTX capable */
 
-#define	IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR	0xC30A	/* PHY_XS SDA/SCL Address Reg */
+
+#define	IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR	0xC30A	/* PHY_XS SDA/SCL Addr Reg */
 #define	IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA	0xC30B	/* PHY_XS SDA/SCL Data Reg */
 #define	IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT	0xC30C	/* PHY_XS SDA/SCL Status Reg */
 
@@ -533,11 +1025,17 @@
 /* General purpose Interrupt Enable */
 #define	IXGBE_SDP0_GPIEN	0x00000001 /* SDP0 */
 #define	IXGBE_SDP1_GPIEN	0x00000002 /* SDP1 */
+#define	IXGBE_SDP2_GPIEN	0x00000004 /* SDP2 */
 #define	IXGBE_GPIE_MSIX_MODE	0x00000010 /* MSI-X mode */
 #define	IXGBE_GPIE_OCD		0x00000020 /* Other Clear Disable */
 #define	IXGBE_GPIE_EIMEN	0x00000040 /* Immediate Interrupt Enable */
 #define	IXGBE_GPIE_EIAME	0x40000000
 #define	IXGBE_GPIE_PBA_SUPPORT	0x80000000
+#define	IXGBE_GPIE_RSC_DELAY_SHIFT	11
+#define	IXGBE_GPIE_VTMODE_MASK	0x0000C000 /* VT Mode Mask */
+#define	IXGBE_GPIE_VTMODE_16	0x00004000 /* 16 VFs 8 queues per VF */
+#define	IXGBE_GPIE_VTMODE_32	0x00008000 /* 32 VFs 4 queues per VF */
+#define	IXGBE_GPIE_VTMODE_64	0x0000C000 /* 64 VFs 2 queues per VF */
 
 /* Transmit Flow Control status */
 #define	IXGBE_TFCS_TXOFF	0x00000001
@@ -578,6 +1076,23 @@
 #define	IXGBE_VMD_CTL_VMDQ_EN		0x00000001
 #define	IXGBE_VMD_CTL_VMDQ_FILTER	0x00000002
 
+/* VT_CTL bitmasks */
+#define	IXGBE_VT_CTL_DIS_DEFPL	0x20000000 /* disable default pool */
+#define	IXGBE_VT_CTL_REPLEN	0x40000000 /* replication enabled */
+#define	IXGBE_VT_CTL_VT_ENABLE	0x00000001  /* Enable VT Mode */
+#define	IXGBE_VT_CTL_POOL_SHIFT	7
+#define	IXGBE_VT_CTL_POOL_MASK	(0x3F << IXGBE_VT_CTL_POOL_SHIFT)
+
+/* VMOLR bitmasks */
+#define	IXGBE_VMOLR_AUPE	0x01000000 /* accept untagged packets */
+#define	IXGBE_VMOLR_ROMPE	0x02000000 /* accept packets in MTA tbl */
+#define	IXGBE_VMOLR_ROPE	0x04000000 /* accept packets in UC tbl */
+#define	IXGBE_VMOLR_BAM		0x08000000 /* accept broadcast packets */
+#define	IXGBE_VMOLR_MPE		0x10000000 /* multicast promiscuous */
+
+/* VFRE bitmask */
+#define	IXGBE_VFRE_ENABLE_ALL	0xFFFFFFFF
+
 /* RDHMPN and TDHMPN bitmasks */
 #define	IXGBE_RDHMPN_RDICADDR		0x007FF800
 #define	IXGBE_RDHMPN_RDICRDREQ		0x00800000
@@ -586,13 +1101,48 @@
 #define	IXGBE_TDHMPN_TDICRDREQ		0x00800000
 #define	IXGBE_TDHMPN_TDICADDR_SHIFT	11
 
+#define	IXGBE_RDMAM_MEM_SEL_SHIFT	13
+#define	IXGBE_RDMAM_DWORD_SHIFT		9
+#define	IXGBE_RDMAM_DESC_COMP_FIFO	1
+#define	IXGBE_RDMAM_DFC_CMD_FIFO	2
+#define	IXGBE_RDMAM_RSC_HEADER_ADDR	3
+#define	IXGBE_RDMAM_TCN_STATUS_RAM	4
+#define	IXGBE_RDMAM_WB_COLL_FIFO	5
+#define	IXGBE_RDMAM_QSC_CNT_RAM		6
+#define	IXGBE_RDMAM_QSC_FCOE_RAM	7
+#define	IXGBE_RDMAM_QSC_QUEUE_CNT	8
+#define	IXGBE_RDMAM_QSC_QUEUE_RAM	0xA
+#define	IXGBE_RDMAM_QSC_RSC_RAM		0xB
+#define	IXGBE_RDMAM_DESC_COM_FIFO_RANGE	135
+#define	IXGBE_RDMAM_DESC_COM_FIFO_COUNT	4
+#define	IXGBE_RDMAM_DFC_CMD_FIFO_RANGE	48
+#define	IXGBE_RDMAM_DFC_CMD_FIFO_COUNT	7
+#define	IXGBE_RDMAM_RSC_HEADER_ADDR_RANGE	32
+#define	IXGBE_RDMAM_RSC_HEADER_ADDR_COUNT	4
+#define	IXGBE_RDMAM_TCN_STATUS_RAM_RANGE	256
+#define	IXGBE_RDMAM_TCN_STATUS_RAM_COUNT	9
+#define	IXGBE_RDMAM_WB_COLL_FIFO_RANGE	8
+#define	IXGBE_RDMAM_WB_COLL_FIFO_COUNT	4
+#define	IXGBE_RDMAM_QSC_CNT_RAM_RANGE	64
+#define	IXGBE_RDMAM_QSC_CNT_RAM_COUNT	4
+#define	IXGBE_RDMAM_QSC_FCOE_RAM_RANGE	512
+#define	IXGBE_RDMAM_QSC_FCOE_RAM_COUNT	5
+#define	IXGBE_RDMAM_QSC_QUEUE_CNT_RANGE	32
+#define	IXGBE_RDMAM_QSC_QUEUE_CNT_COUNT	4
+#define	IXGBE_RDMAM_QSC_QUEUE_RAM_RANGE	128
+#define	IXGBE_RDMAM_QSC_QUEUE_RAM_COUNT	8
+#define	IXGBE_RDMAM_QSC_RSC_RAM_RANGE	32
+#define	IXGBE_RDMAM_QSC_RSC_RAM_COUNT	8
+
+#define	IXGBE_TXDESCIC_READY		0x80000000
+
 /* Receive Checksum Control */
 #define	IXGBE_RXCSUM_IPPCSE	0x00001000   /* IP payload checksum enable */
 #define	IXGBE_RXCSUM_PCSD	0x00002000   /* packet checksum disabled */
 
 /* FCRTL Bit Masks */
-#define	IXGBE_FCRTL_XONE	0x80000000  /* bit 31, XON enable */
-#define	IXGBE_FCRTH_FCEN	0x80000000  /* Rx Flow control enable */
+#define	IXGBE_FCRTL_XONE	0x80000000  /* XON enable */
+#define	IXGBE_FCRTH_FCEN	0x80000000  /* Packet buffer fc enable */
 
 /* PAP bit masks */
 #define	IXGBE_PAP_TXPAUSECNT_MASK	0x0000FFFF /* Pause counter mask */
@@ -602,19 +1152,29 @@
 /* Receive Arbitration Control: 0 Round Robin, 1 DFP */
 #define	IXGBE_RMCS_RAC		0x00000004
 #define	IXGBE_RMCS_DFP		IXGBE_RMCS_RAC /* Deficit Fixed Priority ena */
-#define	IXGBE_RMCS_TFCE_802_3X	0x00000008 /* Tx Priority flow control ena */
-#define	IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority flow control ena */
+#define	IXGBE_RMCS_TFCE_802_3X	0x00000008 /* Tx Priority FC ena */
+#define	IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority FC ena */
 #define	IXGBE_RMCS_ARBDIS	0x00000040 /* Arbitration disable bit */
 
+/* FCCFG Bit Masks */
+#define	IXGBE_FCCFG_TFCE_802_3X		0x00000008 /* Tx link FC enable */
+#define	IXGBE_FCCFG_TFCE_PRIORITY	0x00000010 /* Tx priority FC enable */
 
 /* Interrupt register bitmasks */
 
 /* Extended Interrupt Cause Read */
 #define	IXGBE_EICR_RTX_QUEUE	0x0000FFFF /* RTx Queue Interrupt */
+#define	IXGBE_EICR_FLOW_DIR	0x00010000 /* FDir Exception */
+#define	IXGBE_EICR_RX_MISS	0x00020000 /* Packet Buffer Overrun */
+#define	IXGBE_EICR_PCI		0x00040000 /* PCI Exception */
+#define	IXGBE_EICR_MAILBOX	0x00080000 /* VF to PF Mailbox Interrupt */
 #define	IXGBE_EICR_LSC		0x00100000 /* Link Status Change */
+#define	IXGBE_EICR_LINKSEC	0x00200000 /* PN Threshold */
 #define	IXGBE_EICR_MNG		0x00400000 /* Manageability Event Interrupt */
 #define	IXGBE_EICR_GPI_SDP0	0x01000000 /* Gen Purpose Interrupt on SDP0 */
 #define	IXGBE_EICR_GPI_SDP1	0x02000000 /* Gen Purpose Interrupt on SDP1 */
+#define	IXGBE_EICR_GPI_SDP2	0x04000000 /* Gen Purpose Interrupt on SDP2 */
+#define	IXGBE_EICR_ECC		0x10000000 /* ECC Error */
 #define	IXGBE_EICR_PBUR		0x10000000 /* Packet Buffer Handler Error */
 #define	IXGBE_EICR_DHER		0x20000000 /* Descriptor Handler Error */
 #define	IXGBE_EICR_TCP_TIMER	0x40000000 /* TCP Timer */
@@ -622,10 +1182,16 @@
 
 /* Extended Interrupt Cause Set */
 #define	IXGBE_EICS_RTX_QUEUE	IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define	IXGBE_EICS_FLOW_DIR	IXGBE_EICR_FLOW_DIR  /* FDir Exception */
+#define	IXGBE_EICS_RX_MISS	IXGBE_EICR_RX_MISS   /* Pkt Buffer Overrun */
+#define	IXGBE_EICS_PCI		IXGBE_EICR_PCI /* PCI Exception */
+#define	IXGBE_EICS_MAILBOX	IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
 #define	IXGBE_EICS_LSC		IXGBE_EICR_LSC /* Link Status Change */
 #define	IXGBE_EICS_MNG		IXGBE_EICR_MNG /* MNG Event Interrupt */
 #define	IXGBE_EICS_GPI_SDP0	IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
 #define	IXGBE_EICS_GPI_SDP1	IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define	IXGBE_EICS_GPI_SDP2	IXGBE_EICR_GPI_SDP2  /* SDP2 Gen Purpose Int */
+#define	IXGBE_EICS_ECC		IXGBE_EICR_ECC	/* ECC Error */
 #define	IXGBE_EICS_PBUR		IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
 #define	IXGBE_EICS_DHER		IXGBE_EICR_DHER /* Desc Handler Error */
 #define	IXGBE_EICS_TCP_TIMER	IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -633,10 +1199,16 @@
 
 /* Extended Interrupt Mask Set */
 #define	IXGBE_EIMS_RTX_QUEUE	IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define	IXGBE_EIMS_FLOW_DIR	IXGBE_EICR_FLOW_DIR  /* FDir Exception */
+#define	IXGBE_EIMS_RX_MISS	IXGBE_EICR_RX_MISS   /* Packet Buffer Overrun */
+#define	IXGBE_EIMS_PCI		IXGBE_EICR_PCI	/* PCI Exception */
+#define	IXGBE_EIMS_MAILBOX	IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
 #define	IXGBE_EIMS_LSC		IXGBE_EICR_LSC /* Link Status Change */
 #define	IXGBE_EIMS_MNG		IXGBE_EICR_MNG /* MNG Event Interrupt */
 #define	IXGBE_EIMS_GPI_SDP0	IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
 #define	IXGBE_EIMS_GPI_SDP1	IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define	IXGBE_EIMS_GPI_SDP2	IXGBE_EICR_GPI_SDP2  /* SDP2 Gen Purpose Int */
+#define	IXGBE_EIMS_ECC		IXGBE_EICR_ECC	/* ECC Error */
 #define	IXGBE_EIMS_PBUR		IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
 #define	IXGBE_EIMS_DHER		IXGBE_EICR_DHER /* Descr Handler Error */
 #define	IXGBE_EIMS_TCP_TIMER	IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -644,10 +1216,16 @@
 
 /* Extended Interrupt Mask Clear */
 #define	IXGBE_EIMC_RTX_QUEUE	IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define	IXGBE_EIMC_FLOW_DIR	IXGBE_EICR_FLOW_DIR  /* FDir Exception */
+#define	IXGBE_EIMC_RX_MISS	IXGBE_EICR_RX_MISS   /* Packet Buffer Overrun */
+#define	IXGBE_EIMC_PCI		IXGBE_EICR_PCI	/* PCI Exception */
+#define	IXGBE_EIMC_MAILBOX	IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
 #define	IXGBE_EIMC_LSC		IXGBE_EICR_LSC /* Link Status Change */
 #define	IXGBE_EIMC_MNG		IXGBE_EICR_MNG /* MNG Event Interrupt */
 #define	IXGBE_EIMC_GPI_SDP0	IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
 #define	IXGBE_EIMC_GPI_SDP1	IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define	IXGBE_EIMC_GPI_SDP2	IXGBE_EICR_GPI_SDP2  /* SDP2 Gen Purpose Int */
+#define	IXGBE_EIMC_ECC		IXGBE_EICR_ECC	/* ECC Error */
 #define	IXGBE_EIMC_PBUR		IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
 #define	IXGBE_EIMC_DHER		IXGBE_EICR_DHER /* Desc Handler Error */
 #define	IXGBE_EIMC_TCP_TIMER	IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -668,12 +1246,45 @@
 #define	IXGBE_IMIREXT_CTRL_SYN	0x00020000  /* Check SYN bit in header */
 #define	IXGBE_IMIREXT_CTRL_FIN	0x00040000  /* Check FIN bit in header */
 #define	IXGBE_IMIREXT_CTRL_BP	0x00080000  /* Bypass check of control bits */
+#define	IXGBE_IMIR_SIZE_BP_82599 0x00001000 /* Packet size bypass */
+#define	IXGBE_IMIR_CTRL_URG_82599 0x00002000 /* Check URG bit in header */
+#define	IXGBE_IMIR_CTRL_ACK_82599 0x00004000 /* Check ACK bit in header */
+#define	IXGBE_IMIR_CTRL_PSH_82599 0x00008000 /* Check PSH bit in header */
+#define	IXGBE_IMIR_CTRL_RST_82599 0x00010000 /* Check RST bit in header */
+#define	IXGBE_IMIR_CTRL_SYN_82599 0x00020000 /* Check SYN bit in header */
+#define	IXGBE_IMIR_CTRL_FIN_82599 0x00040000 /* Check FIN bit in header */
+#define	IXGBE_IMIR_CTRL_BP_82599  0x00080000 /* Bypass check of control bits */
+#define	IXGBE_IMIR_LLI_EN_82599   0x00100000 /* Enables low latency Int */
+#define	IXGBE_IMIR_RX_QUEUE_MASK_82599  0x0000007F /* Rx Queue Mask */
+#define	IXGBE_IMIR_RX_QUEUE_SHIFT_82599 21 /* Rx Queue Shift */
+#define	IXGBE_IMIRVP_PRIORITY_MASK	0x00000007 /* VLAN priority mask */
+#define	IXGBE_IMIRVP_PRIORITY_EN	0x00000008 /* VLAN priority enable */
+
+#define	IXGBE_MAX_FTQF_FILTERS		128
+#define	IXGBE_FTQF_PROTOCOL_MASK	0x00000003
+#define	IXGBE_FTQF_PROTOCOL_TCP		0x00000000
+#define	IXGBE_FTQF_PROTOCOL_UDP		0x00000001
+#define	IXGBE_FTQF_PROTOCOL_SCTP	2
+#define	IXGBE_FTQF_PRIORITY_MASK	0x00000007
+#define	IXGBE_FTQF_PRIORITY_SHIFT	2
+#define	IXGBE_FTQF_POOL_MASK		0x0000003F
+#define	IXGBE_FTQF_POOL_SHIFT		8
+#define	IXGBE_FTQF_5TUPLE_MASK_MASK	0x0000001F
+#define	IXGBE_FTQF_5TUPLE_MASK_SHIFT	25
+#define	IXGBE_FTQF_SOURCE_ADDR_MASK	0x1E
+#define	IXGBE_FTQF_DEST_ADDR_MASK	0x1D
+#define	IXGBE_FTQF_SOURCE_PORT_MASK	0x1B
+#define	IXGBE_FTQF_DEST_PORT_MASK	0x17
+#define	IXGBE_FTQF_PROTOCOL_COMP_MASK	0x0F
+#define	IXGBE_FTQF_POOL_MASK_EN		0x40000000
+#define	IXGBE_FTQF_QUEUE_ENABLE		0x80000000
 
 /* Interrupt clear mask */
 #define	IXGBE_IRQ_CLEAR_MASK	0xFFFFFFFF
 
 /* Interrupt Vector Allocation Registers */
 #define	IXGBE_IVAR_REG_NUM	25
+#define	IXGBE_IVAR_REG_NUM_82599	64
 #define	IXGBE_IVAR_TXRX_ENTRY	96
 #define	IXGBE_IVAR_RX_ENTRY	64
 #define	IXGBE_IVAR_RX_QUEUE(_i)	(0 + (_i))
@@ -687,6 +1298,35 @@
 
 #define	IXGBE_IVAR_ALLOC_VAL	0x80 /* Interrupt Allocation valid */
 
+/* ETYPE Queue Filter/Select Bit Masks */
+#define	IXGBE_MAX_ETQF_FILTERS	8
+#define	IXGBE_ETQF_FCOE		0x08000000 /* bit 27 */
+#define	IXGBE_ETQF_BCN		0x10000000 /* bit 28 */
+#define	IXGBE_ETQF_1588		0x40000000 /* bit 30 */
+#define	IXGBE_ETQF_FILTER_EN	0x80000000 /* bit 31 */
+#define	IXGBE_ETQF_POOL_ENABLE	(1 << 26) /* bit 26 */
+
+#define	IXGBE_ETQS_RX_QUEUE	0x007F0000 /* bits 22:16 */
+#define	IXGBE_ETQS_RX_QUEUE_SHIFT	16
+#define	IXGBE_ETQS_LLI		0x20000000 /* bit 29 */
+#define	IXGBE_ETQS_QUEUE_EN	0x80000000 /* bit 31 */
+
+/*
+ * ETQF filter list: one static filter per filter consumer. This is
+ *                   to avoid filter collisions later. Add new filters
+ *                   here!!
+ *
+ * Current filters:
+ *    EAPOL 802.1x (0x888e): Filter 0
+ *    BCN (0x8904):          Filter 1
+ *    FCoE (0x8906):         Filter 2
+ *    1588 (0x88f7):         Filter 3
+ */
+#define	IXGBE_ETQF_FILTER_EAPOL	0
+#define	IXGBE_ETQF_FILTER_BCN	1
+#define	IXGBE_ETQF_FILTER_FCOE	2
+#define	IXGBE_ETQF_FILTER_1588	3
+
 /* VLAN Control Bit Masks */
 #define	IXGBE_VLNCTRL_VET	0x0000FFFF  /* bits 0-15 */
 #define	IXGBE_VLNCTRL_CFI	0x10000000  /* bit 28 */
@@ -694,21 +1334,28 @@
 #define	IXGBE_VLNCTRL_VFE	0x40000000  /* bit 30 */
 #define	IXGBE_VLNCTRL_VME	0x80000000  /* bit 31 */
 
+/* VLAN pool filtering masks */
+#define	IXGBE_VLVF_VIEN		0x80000000  /* filter is valid */
+#define	IXGBE_VLVF_ENTRIES	64
 
 #define	IXGBE_ETHERNET_IEEE_VLAN_TYPE	0x8100  /* 802.1q protocol */
 
 /* STATUS Bit Masks */
 #define	IXGBE_STATUS_LAN_ID	0x0000000C /* LAN ID */
+#define	IXGBE_STATUS_LAN_ID_SHIFT	2  /* LAN ID Shift */
 #define	IXGBE_STATUS_GIO	0x00080000 /* GIO Master Enable Status */
 
 #define	IXGBE_STATUS_LAN_ID_0	0x00000000 /* LAN ID 0 */
 #define	IXGBE_STATUS_LAN_ID_1	0x00000004 /* LAN ID 1 */
 
 /* ESDP Bit Masks */
-#define	IXGBE_ESDP_SDP4		0x00000001 /* SDP4 Data Value */
-#define	IXGBE_ESDP_SDP5		0x00000002 /* SDP5 Data Value */
+#define	IXGBE_ESDP_SDP0		0x00000001
+#define	IXGBE_ESDP_SDP1		0x00000002
+#define	IXGBE_ESDP_SDP4		0x00000010 /* SDP4 Data Value */
+#define	IXGBE_ESDP_SDP5		0x00000020 /* SDP5 Data Value */
+#define	IXGBE_ESDP_SDP6		0x00000040 /* SDP6 Data Value */
 #define	IXGBE_ESDP_SDP4_DIR	0x00000004 /* SDP4 IO direction */
-#define	IXGBE_ESDP_SDP5_DIR	0x00000008 /* SDP5 IO direction */
+#define	IXGBE_ESDP_SDP5_DIR	0x00002000 /* SDP5 IO direction */
 
 /* LEDCTL Bit Masks */
 #define	IXGBE_LED_IVRT_BASE	0x00000040
@@ -731,6 +1378,7 @@
 #define	IXGBE_LED_OFF		0xF
 
 /* AUTOC Bit Masks */
+#define	IXGBE_AUTOC_KX4_KX_SUPP_MASK	0xC0000000
 #define	IXGBE_AUTOC_KX4_SUPP	0x80000000
 #define	IXGBE_AUTOC_KX_SUPP	0x40000000
 #define	IXGBE_AUTOC_PAUSE	0x30000000
@@ -739,26 +1387,43 @@
 #define	IXGBE_AUTOC_AN_RX_LOOSE	0x01000000
 #define	IXGBE_AUTOC_AN_RX_DRIFT	0x00800000
 #define	IXGBE_AUTOC_AN_RX_ALIGN	0x007C0000
+#define	IXGBE_AUTOC_FECA	0x00040000
+#define	IXGBE_AUTOC_FECR	0x00020000
+#define	IXGBE_AUTOC_KR_SUPP	0x00010000
 #define	IXGBE_AUTOC_AN_RESTART	0x00001000
 #define	IXGBE_AUTOC_FLU		0x00000001
 #define	IXGBE_AUTOC_LMS_SHIFT	13
-#define	IXGBE_AUTOC_LMS_MASK	(0x7 << IXGBE_AUTOC_LMS_SHIFT)
+#define	IXGBE_AUTOC_LMS_10G_SERIAL	(0x3 << IXGBE_AUTOC_LMS_SHIFT)
+#define	IXGBE_AUTOC_LMS_KX4_KX_KR	(0x4 << IXGBE_AUTOC_LMS_SHIFT)
+#define	IXGBE_AUTOC_LMS_SGMII_1G_100M	(0x5 << IXGBE_AUTOC_LMS_SHIFT)
+#define	IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN	(0x6 << IXGBE_AUTOC_LMS_SHIFT)
+#define	IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII	(0x7 << IXGBE_AUTOC_LMS_SHIFT)
+#define	IXGBE_AUTOC_LMS_MASK		(0x7 << IXGBE_AUTOC_LMS_SHIFT)
 #define	IXGBE_AUTOC_LMS_1G_LINK_NO_AN	(0x0 << IXGBE_AUTOC_LMS_SHIFT)
 #define	IXGBE_AUTOC_LMS_10G_LINK_NO_AN	(0x1 << IXGBE_AUTOC_LMS_SHIFT)
-#define	IXGBE_AUTOC_LMS_1G_AN	(0x2 << IXGBE_AUTOC_LMS_SHIFT)
-#define	IXGBE_AUTOC_LMS_KX4_AN	(0x4 << IXGBE_AUTOC_LMS_SHIFT)
+#define	IXGBE_AUTOC_LMS_1G_AN		(0x2 << IXGBE_AUTOC_LMS_SHIFT)
+#define	IXGBE_AUTOC_LMS_KX4_AN		(0x4 << IXGBE_AUTOC_LMS_SHIFT)
 #define	IXGBE_AUTOC_LMS_KX4_AN_1G_AN	(0x6 << IXGBE_AUTOC_LMS_SHIFT)
 #define	IXGBE_AUTOC_LMS_ATTACH_TYPE	(0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
 
-#define	IXGBE_AUTOC_1G_PMA_PMD	0x00000200
-#define	IXGBE_AUTOC_10G_PMA_PMD	0x00000180
-#define	IXGBE_AUTOC_10G_PMA_PMD_SHIFT	7
+#define	IXGBE_AUTOC_1G_PMA_PMD_MASK	0x00000200
 #define	IXGBE_AUTOC_1G_PMA_PMD_SHIFT	9
-#define	IXGBE_AUTOC_10G_XAUI	(0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-#define	IXGBE_AUTOC_10G_KX4	(0x1 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-#define	IXGBE_AUTOC_10G_CX4	(0x2 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-#define	IXGBE_AUTOC_1G_BX	(0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
-#define	IXGBE_AUTOC_1G_KX	(0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC_10G_PMA_PMD_MASK	0x00000180
+#define	IXGBE_AUTOC_10G_PMA_PMD_SHIFT	7
+#define	IXGBE_AUTOC_10G_XAUI		(0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC_10G_KX4		(0x1 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC_10G_CX4		(0x2 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC_1G_BX		(0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC_1G_KX		(0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC_1G_SFI		(0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC_1G_KX_BX		(0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+
+#define	IXGBE_AUTOC2_UPPER_MASK	0xFFFF0000
+#define	IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK	0x00030000
+#define	IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT	16
+#define	IXGBE_AUTOC2_10G_KR	(0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC2_10G_XFI	(0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define	IXGBE_AUTOC2_10G_SFI	(0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
 
 /* LINKS Bit Masks */
 #define	IXGBE_LINKS_KX_AN_COMP	0x80000000
@@ -768,6 +1433,7 @@
 #define	IXGBE_LINKS_RX_MODE	0x06000000
 #define	IXGBE_LINKS_TX_MODE	0x01800000
 #define	IXGBE_LINKS_XGXS_EN	0x00400000
+#define	IXGBE_LINKS_SGMII_EN	0x02000000
 #define	IXGBE_LINKS_PCS_1G_EN	0x00200000
 #define	IXGBE_LINKS_1G_AN_EN	0x00100000
 #define	IXGBE_LINKS_KX_AN_IDLE	0x00080000
@@ -777,8 +1443,32 @@
 #define	IXGBE_LINKS_TL_FAULT	0x00001000
 #define	IXGBE_LINKS_SIGNAL	0x00000F00
 
-#define	IXGBE_LINK_UP_TIME	90 /* 9.0 Seconds */
-#define	IXGBE_AUTO_NEG_TIME	45 /* 4.5 Seconds */
+#define	IXGBE_LINKS_SPEED_82599		0x30000000
+#define	IXGBE_LINKS_SPEED_10G_82599	0x30000000
+#define	IXGBE_LINKS_SPEED_1G_82599	0x20000000
+#define	IXGBE_LINKS_SPEED_100_82599	0x10000000
+#define	IXGBE_LINK_UP_TIME		90 /* 9.0 Seconds */
+#define	IXGBE_AUTO_NEG_TIME		45 /* 4.5 Seconds */
+
+/* PCS1GLSTA Bit Masks */
+#define	IXGBE_PCS1GLSTA_LINK_OK		1
+#define	IXGBE_PCS1GLSTA_SYNK_OK		0x10
+#define	IXGBE_PCS1GLSTA_AN_COMPLETE	0x10000
+#define	IXGBE_PCS1GLSTA_AN_PAGE_RX	0x20000
+#define	IXGBE_PCS1GLSTA_AN_TIMED_OUT	0x40000
+#define	IXGBE_PCS1GLSTA_AN_REMOTE_FAULT	0x80000
+#define	IXGBE_PCS1GLSTA_AN_ERROR_RWS	0x100000
+
+#define	IXGBE_PCS1GANA_SYM_PAUSE	0x80
+#define	IXGBE_PCS1GANA_ASM_PAUSE	0x100
+
+/* PCS1GLCTL Bit Masks */
+#define	IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN 0x00040000 /* PCS 1G autoneg to en */
+#define	IXGBE_PCS1GLCTL_FLV_LINK_UP	1
+#define	IXGBE_PCS1GLCTL_FORCE_LINK	0x20
+#define	IXGBE_PCS1GLCTL_LOW_LINK_LATCH	0x40
+#define	IXGBE_PCS1GLCTL_AN_ENABLE	0x10000
+#define	IXGBE_PCS1GLCTL_AN_RESTART	0x20000
 
 /* SW Semaphore Register bitmasks */
 #define	IXGBE_SWSM_SMBI		0x00000001 /* Driver Semaphore bit */
@@ -831,6 +1521,13 @@
 #define	IXGBE_FW_PTR		0x0F
 #define	IXGBE_PBANUM0_PTR	0x15
 #define	IXGBE_PBANUM1_PTR	0x16
+#define	IXGBE_SAN_MAC_ADDR_PTR	0x28
+#define	IXGBE_DEVICE_CAPS	0x2C
+#define	IXGBE_PCIE_MSIX_82599_CAPS	0x72
+#define	IXGBE_PCIE_MSIX_82598_CAPS	0x62
+
+/* MSI-X capability fields masks */
+#define	IXGBE_PCIE_MSIX_TBL_SZ_MASK	0x7FF
 
 /* Legacy EEPROM word offsets */
 #define	IXGBE_ISCSI_BOOT_CAPS		0x0033
@@ -869,6 +1566,11 @@
 #define	IXGBE_EERD_ATTEMPTS 100000
 #endif
 
+#define	IXGBE_SAN_MAC_ADDR_PORT0_OFFSET	0x0
+#define	IXGBE_SAN_MAC_ADDR_PORT1_OFFSET	0x3
+#define	IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP	0x1
+#define	IXGBE_DEVICE_CAPS_FCOE_OFFLOADS	0x2
+
 /* PCI Bus Info */
 #define	IXGBE_PCI_LINK_STATUS		0xB2
 #define	IXGBE_PCI_LINK_WIDTH		0x3F0
@@ -933,6 +1635,7 @@
 #define	IXGBE_RXCTRL_RXEN	0x00000001  /* Enable Receiver */
 #define	IXGBE_RXCTRL_DMBYPS	0x00000002  /* Descriptor Monitor Bypass */
 #define	IXGBE_RXDCTL_ENABLE	0x02000000  /* Enable specific Rx Queue */
+#define	IXGBE_RXDCTL_VME	0x40000000  /* VLAN mode enable */
 
 #define	IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
 #define	IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena	*/
@@ -943,9 +1646,23 @@
 /* Receive Priority Flow Control Enable */
 #define	IXGBE_FCTRL_RPFCE 0x00004000
 #define	IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */
+#define	IXGBE_MFLCN_PMCF	0x00000001 /* Pass MAC Control Frames */
+#define	IXGBE_MFLCN_DPF		0x00000002 /* Discard Pause Frame */
+#define	IXGBE_MFLCN_RPFCE	0x00000004 /* Receive Priority FC Enable */
+#define	IXGBE_MFLCN_RFCE	0x00000008 /* Receive FC Enable */
 
 /* Multiple Receive Queue Control */
 #define	IXGBE_MRQC_RSSEN		0x00000001  /* RSS Enable */
+#define	IXGBE_MRQC_MRQE_MASK		0xF /* Bits 3:0 */
+#define	IXGBE_MRQC_RT8TCEN		0x00000002 /* 8 TC no RSS */
+#define	IXGBE_MRQC_RT4TCEN		0x00000003 /* 4 TC no RSS */
+#define	IXGBE_MRQC_RTRSS8TCEN		0x00000004 /* 8 TC w/ RSS */
+#define	IXGBE_MRQC_RTRSS4TCEN		0x00000005 /* 4 TC w/ RSS */
+#define	IXGBE_MRQC_VMDQEN		0x00000008 /* VMDq2 64 pools no RSS */
+#define	IXGBE_MRQC_VMDQRSS32EN		0x0000000A /* VMDq2 32 pools w/ RSS */
+#define	IXGBE_MRQC_VMDQRSS64EN		0x0000000B /* VMDq2 64 pools w/ RSS */
+#define	IXGBE_MRQC_VMDQRT8TCEN		0x0000000C /* VMDq2/RT 16 pool 8 TC */
+#define	IXGBE_MRQC_VMDQRT4TCEN		0x0000000D /* VMDq2/RT 32 pool 4 TC */
 #define	IXGBE_MRQC_RSS_FIELD_MASK	0xFFFF0000
 #define	IXGBE_MRQC_RSS_FIELD_IPV4_TCP	0x00010000
 #define	IXGBE_MRQC_RSS_FIELD_IPV4	0x00020000
@@ -956,6 +1673,12 @@
 #define	IXGBE_MRQC_RSS_FIELD_IPV4_UDP	0x00400000
 #define	IXGBE_MRQC_RSS_FIELD_IPV6_UDP	0x00800000
 #define	IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
+#define	IXGBE_MRQC_L3L4TXSWEN		0x00008000
+
+/* Queue Drop Enable */
+#define	IXGBE_QDE_ENABLE	0x00000001
+#define	IXGBE_QDE_IDX_MASK	0x00007F00
+#define	IXGBE_QDE_IDX_SHIFT	8
 
 #define	IXGBE_TXD_POPTS_IXSM	0x01	/* Insert IP checksum */
 #define	IXGBE_TXD_POPTS_TXSM	0x02	/* Insert TCP/UDP checksum */
@@ -968,10 +1691,27 @@
 #define	IXGBE_TXD_CMD_VLE	0x40000000 /* Add VLAN tag */
 #define	IXGBE_TXD_STAT_DD	0x00000001 /* Descriptor Done */
 
+#define	IXGBE_RXDADV_IPSEC_STATUS_SECP			0x00020000
+#define	IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL	0x08000000
+#define	IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH		0x10000000
+#define	IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED		0x18000000
+#define	IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK		0x18000000
+
+/* Multiple Transmit Queue Command Register */
+#define	IXGBE_MTQC_RT_ENA	0x1 /* DCB Enable */
+#define	IXGBE_MTQC_VT_ENA	0x2 /* VMDQ2 Enable */
+#define	IXGBE_MTQC_64Q_1PB	0x0 /* 64 queues 1 pack buffer */
+#define	IXGBE_MTQC_32VF		0x8 /* 4 TX Queues per pool w/32VF's */
+#define	IXGBE_MTQC_64VF		0x4 /* 2 TX Queues per pool w/64VF's */
+#define	IXGBE_MTQC_8TC_8TQ	0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
+
 /* Receive Descriptor bit definitions */
 #define	IXGBE_RXD_STAT_DD	0x01    /* Descriptor Done */
 #define	IXGBE_RXD_STAT_EOP	0x02    /* End of Packet */
+#define	IXGBE_RXD_STAT_FLM	0x04    /* FDir Match */
 #define	IXGBE_RXD_STAT_VP	0x08    /* IEEE VLAN Packet */
+#define	IXGBE_RXDADV_NEXTP_MASK	0x000FFFF0 /* Next Descriptor Index */
+#define	IXGBE_RXDADV_NEXTP_SHIFT 0x00000004
 #define	IXGBE_RXD_STAT_UDPCS	0x10    /* UDP xsum calculated */
 #define	IXGBE_RXD_STAT_L4CS	0x20    /* L4 xsum calculated */
 #define	IXGBE_RXD_STAT_IPCS	0x40    /* IP xsum calculated */
@@ -980,6 +1720,10 @@
 #define	IXGBE_RXD_STAT_VEXT	0x200   /* 1st VLAN found */
 #define	IXGBE_RXD_STAT_UDPV	0x400   /* Valid UDP checksum */
 #define	IXGBE_RXD_STAT_DYNINT	0x800   /* Pkt caused INT via DYNINT */
+#define	IXGBE_RXD_STAT_LLINT	0x800   /* Pkt caused Low Latency Interrupt */
+#define	IXGBE_RXD_STAT_TS	0x10000 /* Time Stamp */
+#define	IXGBE_RXD_STAT_SECP	0x20000 /* Security Processing */
+#define	IXGBE_RXD_STAT_LB	0x40000 /* Loopback Status */
 #define	IXGBE_RXD_STAT_ACK	0x8000  /* ACK Packet indication */
 #define	IXGBE_RXD_ERR_CE	0x01    /* CRC Error */
 #define	IXGBE_RXD_ERR_LE	0x02    /* Length Error */
@@ -988,6 +1732,13 @@
 #define	IXGBE_RXD_ERR_USE	0x20    /* Undersize Error */
 #define	IXGBE_RXD_ERR_TCPE	0x40    /* TCP/UDP Checksum Error */
 #define	IXGBE_RXD_ERR_IPE	0x80    /* IP Checksum Error */
+#define	IXGBE_RXDADV_ERR_MASK		0xfff00000 /* RDESC.ERRORS mask */
+#define	IXGBE_RXDADV_ERR_SHIFT		20	/* RDESC.ERRORS shift */
+#define	IXGBE_RXDADV_ERR_FCEOFE		0x80000000 /* FCoEFe/IPE */
+#define	IXGBE_RXDADV_ERR_FCERR		0x00700000 /* FCERR/FDIRERR */
+#define	IXGBE_RXDADV_ERR_FDIR_LEN	0x00100000 /* FDIR Length error */
+#define	IXGBE_RXDADV_ERR_FDIR_DROP	0x00200000 /* FDIR Drop error */
+#define	IXGBE_RXDADV_ERR_FDIR_COLL	0x00400000 /* FDIR Collision error */
 #define	IXGBE_RXDADV_ERR_HBO	0x00800000 /* Header Buffer Overflow */
 #define	IXGBE_RXDADV_ERR_CE	0x01000000 /* CRC Error */
 #define	IXGBE_RXDADV_ERR_LE	0x02000000 /* Length Error */
@@ -1002,8 +1753,29 @@
 #define	IXGBE_RXD_CFI_MASK	0x1000  /* CFI is bit 12 */
 #define	IXGBE_RXD_CFI_SHIFT	12
 
+#define	IXGBE_RXDADV_STAT_DD		IXGBE_RXD_STAT_DD  /* Done */
+#define	IXGBE_RXDADV_STAT_EOP		IXGBE_RXD_STAT_EOP /* End of Packet */
+#define	IXGBE_RXDADV_STAT_FLM		IXGBE_RXD_STAT_FLM /* FDir Match */
+#define	IXGBE_RXDADV_STAT_VP		IXGBE_RXD_STAT_VP  /* IEEE VLAN Pkt */
+#define	IXGBE_RXDADV_STAT_MASK		0x000fffff /* Stat/NEXTP: bit 0-19 */
+#define	IXGBE_RXDADV_STAT_FCEOFS	0x00000040 /* FCoE EOF/SOF Stat */
+#define	IXGBE_RXDADV_STAT_FCSTAT	0x00000030 /* FCoE Pkt Stat */
+#define	IXGBE_RXDADV_STAT_FCSTAT_NOMTCH	0x00000000 /* 00: No Ctxt Match */
+#define	IXGBE_RXDADV_STAT_FCSTAT_NODDP	0x00000010 /* 01: Ctxt w/o DDP */
+#define	IXGBE_RXDADV_STAT_FCSTAT_FCPRSP	0x00000020 /* 10: Recv. FCP_RSP */
+#define	IXGBE_RXDADV_STAT_FCSTAT_DDP	0x00000030 /* 11: Ctxt w/ DDP */
+
+/* PSRTYPE bit definitions */
+#define	IXGBE_PSRTYPE_TCPHDR		0x00000010
+#define	IXGBE_PSRTYPE_UDPHDR		0x00000020
+#define	IXGBE_PSRTYPE_IPV4HDR		0x00000100
+#define	IXGBE_PSRTYPE_IPV6HDR		0x00000200
+
 /* SRRCTL bit definitions */
 #define	IXGBE_SRRCTL_BSIZEPKT_SHIFT	10	/* so many KBs */
+#define	IXGBE_SRRCTL_RDMTS_SHIFT	22
+#define	IXGBE_SRRCTL_RDMTS_MASK		0x01C00000
+#define	IXGBE_SRRCTL_DROP_EN		0x10000000
 #define	IXGBE_SRRCTL_BSIZEPKT_MASK	0x0000007F
 #define	IXGBE_SRRCTL_BSIZEHDR_MASK	0x00003F00
 #define	IXGBE_SRRCTL_DESCTYPE_LEGACY	0x00000000
@@ -1018,7 +1790,10 @@
 
 #define	IXGBE_RXDADV_RSSTYPE_MASK	0x0000000F
 #define	IXGBE_RXDADV_PKTTYPE_MASK	0x0000FFF0
+#define	IXGBE_RXDADV_PKTTYPE_MASK_EX	0x0001FFF0
 #define	IXGBE_RXDADV_HDRBUFLEN_MASK	0x00007FE0
+#define	IXGBE_RXDADV_RSCCNT_MASK	0x001E0000
+#define	IXGBE_RXDADV_RSCCNT_SHIFT	17
 #define	IXGBE_RXDADV_HDRBUFLEN_SHIFT	5
 #define	IXGBE_RXDADV_SPLITHEADER_EN	0x00001000
 #define	IXGBE_RXDADV_SPH		0x8000
@@ -1045,6 +1820,19 @@
 #define	IXGBE_RXDADV_PKTTYPE_UDP	0x00000200 /* UDP hdr present */
 #define	IXGBE_RXDADV_PKTTYPE_SCTP	0x00000400 /* SCTP hdr present */
 #define	IXGBE_RXDADV_PKTTYPE_NFS	0x00000800 /* NFS hdr present */
+#define	IXGBE_RXDADV_PKTTYPE_IPSEC_ESP	0x00001000 /* IPSec ESP */
+#define	IXGBE_RXDADV_PKTTYPE_IPSEC_AH	0x00002000 /* IPSec AH */
+#define	IXGBE_RXDADV_PKTTYPE_LINKSEC	0x00004000 /* LinkSec Encap */
+#define	IXGBE_RXDADV_PKTTYPE_ETQF	0x00008000 /* PKTTYPE is ETQF index */
+#define	IXGBE_RXDADV_PKTTYPE_ETQF_MASK	0x00000070 /* ETQF has 8 indices */
+#define	IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT	4	/* Right-shift 4 bits */
+
+/* Security Processing bit Indication */
+#define	IXGBE_RXDADV_LNKSEC_STATUS_SECP		0x00020000
+#define	IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH	0x08000000
+#define	IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR	0x10000000
+#define	IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK	0x18000000
+#define	IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG	0x18000000
 
 /* Masks to determine if packets should be dropped due to frame errors */
 #define	IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
@@ -1083,6 +1871,78 @@
 #define	__be64	u64
 #endif
 
+enum ixgbe_fdir_pballoc_type {
+	IXGBE_FDIR_PBALLOC_64K = 0,
+	IXGBE_FDIR_PBALLOC_128K,
+	IXGBE_FDIR_PBALLOC_256K,
+};
+#define	IXGBE_FDIR_PBALLOC_SIZE_SHIFT		16
+
+/* Flow Director register values */
+#define	IXGBE_FDIRCTRL_PBALLOC_64K		0x00000001
+#define	IXGBE_FDIRCTRL_PBALLOC_128K		0x00000002
+#define	IXGBE_FDIRCTRL_PBALLOC_256K		0x00000003
+#define	IXGBE_FDIRCTRL_INIT_DONE		0x00000008
+#define	IXGBE_FDIRCTRL_PERFECT_MATCH		0x00000010
+#define	IXGBE_FDIRCTRL_REPORT_STATUS		0x00000020
+#define	IXGBE_FDIRCTRL_REPORT_STATUS_ALWAYS	0x00000080
+#define	IXGBE_FDIRCTRL_DROP_Q_SHIFT		8
+#define	IXGBE_FDIRCTRL_FLEX_SHIFT		16
+#define	IXGBE_FDIRCTRL_SEARCHLIM		0x00800000
+#define	IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT		24
+#define	IXGBE_FDIRCTRL_FULL_THRESH_MASK		0xF0000000
+#define	IXGBE_FDIRCTRL_FULL_THRESH_SHIFT	28
+
+#define	IXGBE_FDIRTCPM_DPORTM_SHIFT		16
+#define	IXGBE_FDIRUDPM_DPORTM_SHIFT		16
+#define	IXGBE_FDIRIP6M_DIPM_SHIFT		16
+#define	IXGBE_FDIRM_VLANID			0x00000001
+#define	IXGBE_FDIRM_VLANP			0x00000002
+#define	IXGBE_FDIRM_POOL			0x00000004
+#define	IXGBE_FDIRM_L3P				0x00000008
+#define	IXGBE_FDIRM_L4P				0x00000010
+#define	IXGBE_FDIRM_FLEX			0x00000020
+#define	IXGBE_FDIRM_DIPv6			0x00000040
+
+#define	IXGBE_FDIRFREE_FREE_MASK		0xFFFF
+#define	IXGBE_FDIRFREE_FREE_SHIFT		0
+#define	IXGBE_FDIRFREE_COLL_MASK		0x7FFF0000
+#define	IXGBE_FDIRFREE_COLL_SHIFT		16
+#define	IXGBE_FDIRLEN_MAXLEN_MASK		0x3F
+#define	IXGBE_FDIRLEN_MAXLEN_SHIFT		0
+#define	IXGBE_FDIRLEN_MAXHASH_MASK		0x7FFF0000
+#define	IXGBE_FDIRLEN_MAXHASH_SHIFT		16
+#define	IXGBE_FDIRUSTAT_ADD_MASK		0xFFFF
+#define	IXGBE_FDIRUSTAT_ADD_SHIFT		0
+#define	IXGBE_FDIRUSTAT_REMOVE_MASK		0xFFFF0000
+#define	IXGBE_FDIRUSTAT_REMOVE_SHIFT		16
+#define	IXGBE_FDIRFSTAT_FADD_MASK		0x00FF
+#define	IXGBE_FDIRFSTAT_FADD_SHIFT		0
+#define	IXGBE_FDIRFSTAT_FREMOVE_MASK		0xFF00
+#define	IXGBE_FDIRFSTAT_FREMOVE_SHIFT		8
+#define	IXGBE_FDIRPORT_DESTINATION_SHIFT	16
+#define	IXGBE_FDIRVLAN_FLEX_SHIFT		16
+#define	IXGBE_FDIRHASH_BUCKET_VALID_SHIFT	15
+#define	IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT	16
+
+#define	IXGBE_FDIRCMD_CMD_ADD_FLOW		0x00000001
+#define	IXGBE_FDIRCMD_CMD_REMOVE_FLOW		0x00000002
+#define	IXGBE_FDIRCMD_CMD_QUERY_REM_FILT	0x00000003
+#define	IXGBE_FDIRCMD_CMD_QUERY_REM_HASH	0x00000007
+#define	IXGBE_FDIRCMD_FILTER_UPDATE		0x00000008
+#define	IXGBE_FDIRCMD_IPv6DMATCH		0x00000010
+#define	IXGBE_FDIRCMD_L4TYPE_UDP		0x00000020
+#define	IXGBE_FDIRCMD_L4TYPE_TCP		0x00000040
+#define	IXGBE_FDIRCMD_L4TYPE_SCTP		0x00000060
+#define	IXGBE_FDIRCMD_IPV6			0x00000080
+#define	IXGBE_FDIRCMD_DROP			0x00000200
+#define	IXGBE_FDIRCMD_INT			0x00000400
+#define	IXGBE_FDIRCMD_LAST			0x00000800
+#define	IXGBE_FDIRCMD_COLLISION			0x00001000
+#define	IXGBE_FDIRCMD_QUEUE_EN			0x00008000
+#define	IXGBE_FDIRCMD_RX_QUEUE_SHIFT		16
+#define	IXGBE_FDIRCMD_VT_POOL_SHIFT		24
+
 /* Transmit Descriptor - Legacy */
 struct ixgbe_legacy_tx_desc {
 	u64 buffer_addr;	/* Address of the descriptor's data buffer */
@@ -1171,6 +2031,9 @@
 
 /* Adv Transmit Descriptor Config Masks */
 #define	IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buffer length(bytes) */
+#define	IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */
+#define	IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */
+#define	IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK	0x000001FF /* IPSec ESP length */
 #define	IXGBE_ADVTXD_DTYP_MASK  0x00F00000 /* DTYP mask */
 #define	IXGBE_ADVTXD_DTYP_CTXT  0x00200000 /* Advanced Context Desc */
 #define	IXGBE_ADVTXD_DTYP_DATA  0x00300000 /* Advanced Data Descriptor */
@@ -1206,6 +2069,19 @@
 #define	IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800  /* L4 Packet TYPE of TCP */
 #define	IXGBE_ADVTXD_TUCMD_L4T_SCTP	0x00001000  /* L4 Packet TYPE of SCTP */
 #define	IXGBE_ADVTXD_TUCMD_MKRREQ  0x00002000 /* Req requires Markers and CRC */
+#define	IXGBE_ADVTXD_POPTS_IPSEC  0x00000400 /* IPSec offload request */
+#define	IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
+#define	IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000 /* ESP Encrypt Enable */
+#define	IXGBE_ADVTXT_TUCMD_FCOE		0x00008000	/* FCoE Frame Type */
+#define	IXGBE_ADVTXD_FCOEF_EOF_MASK	(0x3 << 10)	/* FC EOF index */
+#define	IXGBE_ADVTXD_FCOEF_SOF		((1 << 2) << 10) /* FC SOF index */
+#define	IXGBE_ADVTXD_FCOEF_PARINC	((1 << 3) << 10) /* Rel_Off in F_CTL */
+#define	IXGBE_ADVTXD_FCOEF_ORIE	((1 << 4) << 10) /* Orientation: End */
+#define	IXGBE_ADVTXD_FCOEF_ORIS	((1 << 5) << 10) /* Orientation: Start */
+#define	IXGBE_ADVTXD_FCOEF_EOF_N	(0x0 << 10)	/* 00: EOFn */
+#define	IXGBE_ADVTXD_FCOEF_EOF_T	(0x1 << 10)	/* 01: EOFt */
+#define	IXGBE_ADVTXD_FCOEF_EOF_NI	(0x2 << 10)	/* 10: EOFni */
+#define	IXGBE_ADVTXD_FCOEF_EOF_A	(0x3 << 10)	/* 11: EOFa */
 #define	IXGBE_ADVTXD_L4LEN_SHIFT   8  /* Adv ctxt L4LEN shift */
 #define	IXGBE_ADVTXD_MSS_SHIFT	16  /* Adv ctxt MSS shift */
 
@@ -1219,13 +2095,15 @@
 #define	IXGBE_LINK_SPEED_10GB_FULL 0x0080
 #define	IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
 	IXGBE_LINK_SPEED_10GB_FULL)
+#define	IXGBE_LINK_SPEED_82599_AUTONEG (IXGBE_LINK_SPEED_100_FULL | \
+	IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_10GB_FULL)
 
 /* Physical layer type */
 typedef u32 ixgbe_physical_layer;
 #define	IXGBE_PHYSICAL_LAYER_UNKNOWN		0
 #define	IXGBE_PHYSICAL_LAYER_10GBASE_T		0x0001
 #define	IXGBE_PHYSICAL_LAYER_1000BASE_T		0x0002
-#define	IXGBE_PHYSICAL_LAYER_100BASE_T		0x0004
+#define	IXGBE_PHYSICAL_LAYER_100BASE_TX		0x0004
 #define	IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU	0x0008
 #define	IXGBE_PHYSICAL_LAYER_10GBASE_LR		0x0010
 #define	IXGBE_PHYSICAL_LAYER_10GBASE_LRM	0x0020
@@ -1234,6 +2112,47 @@
 #define	IXGBE_PHYSICAL_LAYER_10GBASE_CX4	0x0100
 #define	IXGBE_PHYSICAL_LAYER_1000BASE_KX	0x0200
 #define	IXGBE_PHYSICAL_LAYER_1000BASE_BX	0x0400
+#define	IXGBE_PHYSICAL_LAYER_10GBASE_KR		0x0800
+
+/* Software ATR hash keys */
+#define	IXGBE_ATR_BUCKET_HASH_KEY	0xE214AD3D
+#define	IXGBE_ATR_SIGNATURE_HASH_KEY	0x14364D17
+
+/* Software ATR input stream offsets and masks */
+#define	IXGBE_ATR_VLAN_OFFSET		0
+#define	IXGBE_ATR_SRC_IPV6_OFFSET	2
+#define	IXGBE_ATR_SRC_IPV4_OFFSET	14
+#define	IXGBE_ATR_DST_IPV6_OFFSET	18
+#define	IXGBE_ATR_DST_IPV4_OFFSET	30
+#define	IXGBE_ATR_SRC_PORT_OFFSET	34
+#define	IXGBE_ATR_DST_PORT_OFFSET	36
+#define	IXGBE_ATR_FLEX_BYTE_OFFSET	38
+#define	IXGBE_ATR_VM_POOL_OFFSET	40
+#define	IXGBE_ATR_L4TYPE_OFFSET		41
+
+#define	IXGBE_ATR_L4TYPE_MASK		0x3
+#define	IXGBE_ATR_L4TYPE_IPV6_MASK	0x4
+#define	IXGBE_ATR_L4TYPE_UDP		0x1
+#define	IXGBE_ATR_L4TYPE_TCP		0x2
+#define	IXGBE_ATR_L4TYPE_SCTP		0x3
+#define	IXGBE_ATR_HASH_MASK		0x7fff
+
+/* Flow Director ATR input struct. */
+struct ixgbe_atr_input {
+	/*
+	 * Byte layout in order, all values with MSB first:
+	 *
+	 * vlan_id	- 2 bytes
+	 * src_ip	- 16 bytes
+	 * dst_ip	- 16 bytes
+	 * src_port	- 2 bytes
+	 * dst_port	- 2 bytes
+	 * flex_bytes	- 2 bytes
+	 * vm_pool	- 1 byte
+	 * l4type	- 1 byte
+	 */
+	u8 byte_stream[42];
+};
 
 enum ixgbe_eeprom_type {
 	ixgbe_eeprom_uninitialized = 0,
@@ -1244,13 +2163,16 @@
 enum ixgbe_mac_type {
 	ixgbe_mac_unknown = 0,
 	ixgbe_mac_82598EB,
+	ixgbe_mac_82599EB,
 	ixgbe_num_macs
 };
 
 enum ixgbe_phy_type {
 	ixgbe_phy_unknown = 0,
+	ixgbe_phy_none,
 	ixgbe_phy_tn,
 	ixgbe_phy_qt,
+	ixgbe_phy_cu_unknown,
 	ixgbe_phy_xaui,
 	ixgbe_phy_nl,
 	ixgbe_phy_tw_tyco,
@@ -1258,6 +2180,8 @@
 	ixgbe_phy_sfp_avago,
 	ixgbe_phy_sfp_ftl,
 	ixgbe_phy_sfp_unknown,
+	ixgbe_phy_sfp_intel,
+	ixgbe_phy_sfp_unsupported, /* Enforce bit set with unsupported module */
 	ixgbe_phy_generic
 };
 
@@ -1269,11 +2193,19 @@
  * 0    SFP_DA_CU
  * 1    SFP_SR
  * 2    SFP_LR
+ * 3    SFP_DA_CU_CORE0 - 82599-specific
+ * 4    SFP_DA_CU_CORE1 - 82599-specific
+ * 5    SFP_SR/LR_CORE0 - 82599-specific
+ * 6    SFP_SR/LR_CORE1 - 82599-specific
  */
 enum ixgbe_sfp_type {
 	ixgbe_sfp_type_da_cu = 0,
 	ixgbe_sfp_type_sr = 1,
 	ixgbe_sfp_type_lr = 2,
+	ixgbe_sfp_type_da_cu_core0 = 3,
+	ixgbe_sfp_type_da_cu_core1 = 4,
+	ixgbe_sfp_type_srlr_core0 = 5,
+	ixgbe_sfp_type_srlr_core1 = 6,
 	ixgbe_sfp_type_not_present = 0xFFFE,
 	ixgbe_sfp_type_unknown = 0xFFFF
 };
@@ -1287,7 +2219,7 @@
 };
 
 /* Flow Control Settings */
-enum ixgbe_fc_type {
+enum ixgbe_fc_mode {
 	ixgbe_fc_none = 0,
 	ixgbe_fc_rx_pause,
 	ixgbe_fc_tx_pause,
@@ -1332,7 +2264,6 @@
 struct ixgbe_addr_filter_info {
 	u32 num_mc_addrs;
 	u32 rar_used_count;
-	u32 mc_addr_in_rar_count;
 	u32 mta_in_use;
 	u32 overflow_promisc;
 	bool user_set_promisc;
@@ -1343,6 +2274,9 @@
 	enum ixgbe_bus_speed speed;
 	enum ixgbe_bus_width width;
 	enum ixgbe_bus_type type;
+
+	u16 func;
+	u16 lan_id;
 };
 
 /* Flow control parameters */
@@ -1352,8 +2286,10 @@
 	u16 pause_time; /* Flow Control Pause timer */
 	bool send_xon; /* Flow control send XON */
 	bool strict_ieee; /* Strict IEEE mode */
-	enum ixgbe_fc_type type; /* Type of flow control */
-	enum ixgbe_fc_type original_type;
+	bool disable_fc_autoneg; /* Do not autonegotiate FC */
+	bool fc_was_autonegged; /* Is current_mode the result of autonegging? */
+	enum ixgbe_fc_mode current_mode; /* FC mode in effect */
+	enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */
 };
 
 /* Statistics counters collected by the MAC */
@@ -1413,6 +2349,21 @@
 	u64 qptc[16];
 	u64 qbrc[16];
 	u64 qbtc[16];
+	u64 qprdc[16];
+	u64 pxon2offc[8];
+	u64 fdirustat_add;
+	u64 fdirustat_remove;
+	u64 fdirfstat_fadd;
+	u64 fdirfstat_fremove;
+	u64 fdirmatch;
+	u64 fdirmiss;
+	u64 fccrc;
+	u64 fclast;
+	u64 fcoerpdc;
+	u64 fcoeprc;
+	u64 fcoeptc;
+	u64 fcoedwrc;
+	u64 fcoedwtc;
 };
 
 /* forward declaration */
@@ -1437,12 +2388,18 @@
 	s32 (*start_hw)(struct ixgbe_hw *);
 	s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
 	enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
-	s32 (*get_supported_physical_layer)(struct ixgbe_hw *);
+	u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
 	s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
+	s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *);
+	s32 (*set_san_mac_addr)(struct ixgbe_hw *, u8 *);
+	s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
 	s32 (*stop_adapter)(struct ixgbe_hw *);
 	s32 (*get_bus_info)(struct ixgbe_hw *);
+	void (*set_lan_id)(struct ixgbe_hw *);
 	s32 (*read_analog_reg8)(struct ixgbe_hw *, u32, u8 *);
 	s32 (*write_analog_reg8)(struct ixgbe_hw *, u32, u8);
+	s32 (*setup_sfp)(struct ixgbe_hw *);
+	s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
 
 	/* Link */
 	s32 (*setup_link)(struct ixgbe_hw *);
@@ -1461,6 +2418,7 @@
 	/* RAR, Multicast, VLAN */
 	s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32);
 	s32 (*clear_rar)(struct ixgbe_hw *, u32);
+	s32 (*insert_mac_addr)(struct ixgbe_hw *, u8 *, u32);
 	s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
 	s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
 	s32 (*init_rx_addrs)(struct ixgbe_hw *);
@@ -1475,12 +2433,13 @@
 	s32 (*init_uta_tables)(struct ixgbe_hw *);
 
 	/* Flow Control */
-	s32 (*setup_fc)(struct ixgbe_hw *, s32);
+	s32 (*fc_enable)(struct ixgbe_hw *, s32);
 };
 
 struct ixgbe_phy_operations {
 	s32 (*identify)(struct ixgbe_hw *);
 	s32 (*identify_sfp)(struct ixgbe_hw *);
+	s32 (*init)(struct ixgbe_hw *);
 	s32 (*reset)(struct ixgbe_hw *);
 	s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
 	s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
@@ -1493,6 +2452,7 @@
 	s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
 	s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8, u8 *);
 	s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
+	void (*i2c_bus_clear)(struct ixgbe_hw *);
 };
 
 struct ixgbe_eeprom_info {
@@ -1508,17 +2468,21 @@
 	enum ixgbe_mac_type		type;
 	u8				addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
 	u8				perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+	u8				san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
 	s32				mc_filter_type;
 	u32				mcft_size;
 	u32				vft_size;
 	u32				num_rar_entries;
+	u32				rar_highwater;
 	u32				max_tx_queues;
 	u32				max_rx_queues;
-	u32				link_attach_type;
-	u32				link_mode_select;
-	bool				link_settings_loaded;
+	u32				max_msix_vectors;
+	bool				msix_vectors_from_pcie;
+	u32				orig_autoc;
+	u32				orig_autoc2;
+	bool				orig_link_settings_stored;
 	bool				autoneg;
-	bool				autoneg_failed;
+	bool				autoneg_succeeded;
 };
 
 struct ixgbe_phy_info {
@@ -1527,11 +2491,13 @@
 	u32				addr;
 	u32				id;
 	enum ixgbe_sfp_type		sfp_type;
+	bool				sfp_setup_needed;
 	u32				revision;
 	enum ixgbe_media_type		media_type;
 	bool				reset_disable;
 	ixgbe_autoneg_advertised	autoneg_advertised;
 	bool				autoneg_wait_to_complete;
+	bool				multispeed_fiber;
 };
 
 struct ixgbe_hw {
@@ -1576,6 +2542,8 @@
 #define	IXGBE_ERR_I2C				-18
 #define	IXGBE_ERR_SFP_NOT_SUPPORTED		-19
 #define	IXGBE_ERR_SFP_NOT_PRESENT		-20
+#define	IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT	-21
+#define	IXGBE_ERR_NO_SAN_ADDR_PTR		-22
 #define	IXGBE_NOT_IMPLEMENTED			0x7FFFFFFF
 
 #ifndef UNREFERENCED_PARAMETER