--- old/usr/src/uts/common/io/ixgbe/ixgbe_main.c	Thu Jan 14 14:49:27 2016
+++ new/usr/src/uts/common/io/ixgbe/ixgbe_main.c	Thu Jan 14 14:49:27 2016
@@ -29,11 +29,13 @@
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  * Copyright (c) 2013 Saso Kiselkov. All rights reserved.
  * Copyright (c) 2013 OSN Online Service Nuernberg GmbH. All rights reserved.
+ * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #include "ixgbe_sw.h"
 
 static char ixgbe_ident[] = "Intel 10Gb Ethernet";
+/* LINTED E_STATIC_UNUSED */
 static char ixgbe_version[] = "ixgbe 1.1.7";
 
 /*
@@ -314,11 +316,11 @@
 	16,		/* maximum number of ring vectors */
 	2,		/* maximum number of other vectors */
 	(IXGBE_EICR_LSC
-	| IXGBE_EICR_GPI_SDP1
-	| IXGBE_EICR_GPI_SDP2), /* "other" interrupt types handled */
+	| IXGBE_EICR_GPI_SDP1_X540
+	| IXGBE_EICR_GPI_SDP2_X540), /* "other" interrupt types handled */
 
-	(IXGBE_SDP1_GPIEN
-	| IXGBE_SDP2_GPIEN), /* "other" interrupt types enable mask */
+	(IXGBE_SDP1_GPIEN_X540
+	| IXGBE_SDP2_GPIEN_X540), /* "other" interrupt types enable mask */
 
 	(IXGBE_FLAG_DCA_CAPABLE
 	| IXGBE_FLAG_RSS_CAPABLE
@@ -326,6 +328,35 @@
 	| IXGBE_FLAG_RSC_CAPABLE) /* capability flags */
 };
 
+static adapter_info_t ixgbe_X550_cap = {
+	128,		/* maximum number of rx queues */
+	1,		/* minimum number of rx queues */
+	128,		/* default number of rx queues */
+	64,		/* maximum number of rx groups */
+	1,		/* minimum number of rx groups */
+	1,		/* default number of rx groups */
+	128,		/* maximum number of tx queues */
+	1,		/* minimum number of tx queues */
+	8,		/* default number of tx queues */
+	15500,		/* maximum MTU size */
+	0xFF8,		/* maximum interrupt throttle rate */
+	0,		/* minimum interrupt throttle rate */
+	200,		/* default interrupt throttle rate */
+	64,		/* maximum total msix vectors */
+	16,		/* maximum number of ring vectors */
+	2,		/* maximum number of other vectors */
+	(IXGBE_EICR_LSC
+	| IXGBE_SDP1_GPIEN_X550
+	| IXGBE_SDP2_GPIEN_X550), /* "other" interrupt types handled */
+
+	(IXGBE_SDP1_GPIEN_X550
+	| IXGBE_SDP2_GPIEN_X550), /* "other" interrupt types enable mask */
+
+	(IXGBE_FLAG_RSS_CAPABLE
+	| IXGBE_FLAG_VMDQ_CAPABLE
+	| IXGBE_FLAG_RSC_CAPABLE) /* capability flags */
+};
+
 /*
  * Module Initialization Functions.
  */
@@ -605,7 +636,7 @@
 	}
 	ixgbe->attach_progress |= ATTACH_PROGRESS_ENABLE_INTR;
 
-	ixgbe_log(ixgbe, "%s, %s", ixgbe_ident, ixgbe_version);
+	ixgbe_log(ixgbe, "%s", ixgbe_ident);
 	atomic_or_32(&ixgbe->ixgbe_state, IXGBE_INITIALIZED);
 
 	return (DDI_SUCCESS);
@@ -957,6 +988,16 @@
 		 */
 		break;
 
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+		IXGBE_DEBUGLOG_0(ixgbe, "identify X550 adapter\n");
+		ixgbe->capab = &ixgbe_X550_cap;
+
+		if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
+			ixgbe->capab->flags |= IXGBE_FLAG_SFP_PLUG_CAPABLE;
+
+		break;
+
 	default:
 		IXGBE_DEBUGLOG_1(ixgbe,
 		    "adapter not supported in ixgbe_identify_hardware(): %d\n",
@@ -2191,7 +2232,7 @@
 	reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->hw_index));
 	reg_val |= IXGBE_RXDCTL_ENABLE;	/* enable queue */
 
-	/* Not a valid value for 82599 or X540 */
+	/* Not a valid value for 82599, X540 or X550 */
 	if (hw->mac.type == ixgbe_mac_82598EB) {
 		reg_val |= 0x0020;	/* pthresh */
 	}
@@ -2198,7 +2239,9 @@
 	IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->hw_index), reg_val);
 
 	if (hw->mac.type == ixgbe_mac_82599EB ||
-	    hw->mac.type == ixgbe_mac_X540) {
+	    hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550EM_x) {
 		reg_val = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
 		reg_val |= (IXGBE_RDRXCTL_CRCSTRIP | IXGBE_RDRXCTL_AGGDIS);
 		IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg_val);
@@ -2496,6 +2539,8 @@
 
 			case ixgbe_mac_82599EB:
 			case ixgbe_mac_X540:
+			case ixgbe_mac_X550:
+			case ixgbe_mac_X550EM_x:
 				IXGBE_WRITE_REG(hw, IXGBE_TQSM(i >> 2),
 				    ring_mapping);
 				break;
@@ -2515,6 +2560,8 @@
 
 		case ixgbe_mac_82599EB:
 		case ixgbe_mac_X540:
+		case ixgbe_mac_X550:
+		case ixgbe_mac_X550EM_x:
 			IXGBE_WRITE_REG(hw, IXGBE_TQSM(i >> 2), ring_mapping);
 			break;
 
@@ -2531,10 +2578,12 @@
 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg_val);
 
 	/*
-	 * enable DMA for 82599 and X540 parts
+	 * enable DMA for 82599, X540 and X550 parts
 	 */
 	if (hw->mac.type == ixgbe_mac_82599EB ||
-	    hw->mac.type == ixgbe_mac_X540) {
+	    hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550EM_x) {
 		/* DMATXCTL.TE must be set after all Tx config is complete */
 		reg_val = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
 		reg_val |= IXGBE_DMATXCTL_TE;
@@ -2647,6 +2696,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		/*
 		 * Enable VMDq-only.
 		 */
@@ -2741,6 +2792,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		/*
 		 * Enable RSS & Setup RSS Hash functions
 		 */
@@ -2787,7 +2840,9 @@
 	IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
 
 	if (hw->mac.type == ixgbe_mac_82599EB ||
-	    hw->mac.type == ixgbe_mac_X540) {
+	    hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550EM_x) {
 		/*
 		 * Enable Virtualization and Replication.
 		 */
@@ -2999,6 +3054,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		/*
 		 * 82599 supports the following combination:
 		 * vmdq no. x rss no.
@@ -3008,7 +3065,7 @@
 		 * However 8 rss queue per pool (vmdq) is sufficient for
 		 * most cases.
 		 *
-		 * For now, treat X540 like the 82599.
+		 * For now, treat X540 and X550 like the 82599.
 		 */
 		ring_per_group = ixgbe->num_rx_rings / ixgbe->num_rx_groups;
 		if (ixgbe->num_rx_groups == 1) {
@@ -3171,9 +3228,11 @@
 	ixgbe->relax_order_enable = ixgbe_get_prop(ixgbe,
 	    PROP_RELAX_ORDER_ENABLE, 0, 1, DEFAULT_RELAX_ORDER_ENABLE);
 
-	/* Head Write Back not recommended for 82599 and X540 */
+	/* Head Write Back not recommended for 82599, X540 and X550 */
 	if (hw->mac.type == ixgbe_mac_82599EB ||
-	    hw->mac.type == ixgbe_mac_X540) {
+	    hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550EM_x) {
 		ixgbe->tx_head_wb_enable = B_FALSE;
 	}
 
@@ -3196,7 +3255,7 @@
 	}
 
 	/*
-	 * ixgbe LRO only been supported by 82599 and X540 now
+	 * ixgbe LRO only supported by 82599, X540 and X550
 	 */
 	if (hw->mac.type == ixgbe_mac_82598EB) {
 		ixgbe->lro_enable = B_FALSE;
@@ -3226,11 +3285,13 @@
 	    ixgbe->capab->max_intr_throttle,
 	    ixgbe->capab->def_intr_throttle);
 	/*
-	 * 82599 and X540 require the interrupt throttling rate is
-	 * a multiple of 8. This is enforced by the register
-	 * definiton.
+	 * 82599, X540 and X550 require the interrupt throttling rate is
+	 * a multiple of 8. This is enforced by the register definiton.
 	 */
-	if (hw->mac.type == ixgbe_mac_82599EB || hw->mac.type == ixgbe_mac_X540)
+	if (hw->mac.type == ixgbe_mac_82599EB ||
+	    hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550EM_x)
 		ixgbe->intr_throttling[0] = ixgbe->intr_throttling[0] & 0xFF8;
 
 	hw->allow_unsupported_sfp = ixgbe_get_prop(ixgbe,
@@ -3329,7 +3390,7 @@
 
 	if (setup_hw) {
 		if (ixgbe_setup_link(&ixgbe->hw, autoneg_advertised,
-		    ixgbe->param_adv_autoneg_cap, B_TRUE) != IXGBE_SUCCESS) {
+		    ixgbe->param_adv_autoneg_cap) != IXGBE_SUCCESS) {
 			ixgbe_notice(ixgbe, "Setup link failed on this "
 			    "device.");
 			return (IXGBE_FAILURE);
@@ -3422,18 +3483,18 @@
 	struct ixgbe_hw *hw = &ixgbe->hw;
 
 	mutex_enter(&ixgbe->gen_lock);
-	if (eicr & IXGBE_EICR_GPI_SDP1) {
+	if (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw)) {
 		/* clear the interrupt */
-		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
+		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
 
 		/* if link up, do multispeed fiber setup */
 		(void) ixgbe_setup_link(hw, IXGBE_LINK_SPEED_82599_AUTONEG,
-		    B_TRUE, B_TRUE);
+		    B_TRUE);
 		ixgbe_driver_link_check(ixgbe);
 		ixgbe_get_hw_state(ixgbe);
-	} else if (eicr & IXGBE_EICR_GPI_SDP2) {
+	} else if (eicr & IXGBE_EICR_GPI_SDP2_BY_MAC(hw)) {
 		/* clear the interrupt */
-		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
+		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2_BY_MAC(hw));
 
 		/* if link up, do sfp module setup */
 		(void) hw->mac.ops.setup_sfp(hw);
@@ -3440,7 +3501,7 @@
 
 		/* do multispeed fiber setup */
 		(void) ixgbe_setup_link(hw, IXGBE_LINK_SPEED_82599_AUTONEG,
-		    B_TRUE, B_TRUE);
+		    B_TRUE);
 		ixgbe_driver_link_check(ixgbe);
 		ixgbe_get_hw_state(ixgbe);
 	}
@@ -3476,7 +3537,7 @@
 	(void) ixgbe_check_link(hw, &speed, &link_up, false);
 
 	/* check over-temp condition */
-	if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) ||
+	if (((eicr & IXGBE_EICR_GPI_SDP0_BY_MAC(hw)) && (!link_up)) ||
 	    (eicr & IXGBE_EICR_LSC)) {
 		if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP) {
 			atomic_or_32(&ixgbe->ixgbe_state, IXGBE_OVERTEMP);
@@ -3672,7 +3733,7 @@
 	 * Finally(!), if there's a valid "mac-address" property (created
 	 * if we netbooted from this interface), we must use this instead
 	 * of any of the above to ensure that the NFS/install server doesn't
-	 * get confused by the address changing as Solaris takes over!
+	 * get confused by the address changing as illumos takes over!
 	 */
 	err = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, ixgbe->dip,
 	    DDI_PROP_DONTPASS, "mac-address", &bytes, &nelts);
@@ -3862,8 +3923,8 @@
 
 		/*
 		 * General purpose interrupt enable.
-		 * For 82599 or X540, extended interrupt automask enable
-		 * only in MSI or MSI-X mode
+		 * For 82599, X540 and X550, extended interrupt
+		 * automask enable only in MSI or MSI-X mode
 		 */
 		if ((hw->mac.type == ixgbe_mac_82598EB) ||
 		    (ixgbe->intr_type == DDI_INTR_TYPE_MSI)) {
@@ -3879,6 +3940,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		gpie |= ixgbe->capab->other_gpie;
 
 		/* Enable RSC Delay 8us when LRO enabled  */
@@ -4073,6 +4136,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		reg = IXGBE_READ_REG(&ixgbe->hw, IXGBE_AUTOC);
 		reg |= (IXGBE_AUTOC_FLU |
 		    IXGBE_AUTOC_10G_KX4);
@@ -4079,7 +4144,7 @@
 		IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_AUTOC, reg);
 
 		(void) ixgbe_setup_link(&ixgbe->hw, IXGBE_LINK_SPEED_10GB_FULL,
-		    B_FALSE, B_TRUE);
+		    B_FALSE);
 		break;
 
 	default:
@@ -4139,6 +4204,8 @@
 static void
 ixgbe_intr_other_work(ixgbe_t *ixgbe, uint32_t eicr)
 {
+	struct ixgbe_hw *hw = &ixgbe->hw;
+
 	ASSERT(mutex_owned(&ixgbe->gen_lock));
 
 	/*
@@ -4153,7 +4220,7 @@
 	 * check for fan failure on adapters with fans
 	 */
 	if ((ixgbe->capab->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) &&
-	    (eicr & IXGBE_EICR_GPI_SDP1)) {
+	    (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) {
 		atomic_or_32(&ixgbe->ixgbe_state, IXGBE_OVERTEMP);
 
 		/*
@@ -4174,7 +4241,7 @@
 		    "Action: Replace the adapter.\n");
 
 		/* re-enable the interrupt, which was automasked */
-		ixgbe->eims |= IXGBE_EICR_GPI_SDP1;
+		ixgbe->eims |= IXGBE_EICR_GPI_SDP1_BY_MAC(hw);
 	}
 
 	/*
@@ -4181,7 +4248,8 @@
 	 * Do SFP check for adapters with hot-plug capability
 	 */
 	if ((ixgbe->capab->flags & IXGBE_FLAG_SFP_PLUG_CAPABLE) &&
-	    ((eicr & IXGBE_EICR_GPI_SDP1) || (eicr & IXGBE_EICR_GPI_SDP2))) {
+	    ((eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw)) ||
+	     (eicr & IXGBE_EICR_GPI_SDP2_BY_MAC(hw)))) {
 		ixgbe->eicr = eicr;
 		if ((ddi_taskq_dispatch(ixgbe->sfp_taskq,
 		    ixgbe_sfp_check, (void *)ixgbe,
@@ -4195,7 +4263,7 @@
 	 * Do over-temperature check for adapters with temp sensor
 	 */
 	if ((ixgbe->capab->flags & IXGBE_FLAG_TEMP_SENSOR_CAPABLE) &&
-	    ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
+	    ((eicr & IXGBE_EICR_GPI_SDP0_BY_MAC(hw)) || (eicr & IXGBE_EICR_LSC))) {
 		ixgbe->eicr = eicr;
 		if ((ddi_taskq_dispatch(ixgbe->overtemp_taskq,
 		    ixgbe_overtemp_check, (void *)ixgbe,
@@ -4292,6 +4360,8 @@
 
 			case ixgbe_mac_82599EB:
 			case ixgbe_mac_X540:
+			case ixgbe_mac_X550:
+			case ixgbe_mac_X550EM_x:
 				ixgbe->eimc = IXGBE_82599_OTHER_INTR;
 				IXGBE_WRITE_REG(hw, IXGBE_EIMC, ixgbe->eimc);
 				break;
@@ -4386,6 +4456,8 @@
 
 		case ixgbe_mac_82599EB:
 		case ixgbe_mac_X540:
+		case ixgbe_mac_X550:
+		case ixgbe_mac_X550EM_x:
 			ixgbe->eimc = IXGBE_82599_OTHER_INTR;
 			IXGBE_WRITE_REG(hw, IXGBE_EIMC, ixgbe->eimc);
 			break;
@@ -4466,6 +4538,8 @@
 
 			case ixgbe_mac_82599EB:
 			case ixgbe_mac_X540:
+			case ixgbe_mac_X550:
+			case ixgbe_mac_X550EM_x:
 				ixgbe->eims |= IXGBE_EICR_RTX_QUEUE;
 				ixgbe_intr_other_work(ixgbe, eicr);
 				break;
@@ -4867,6 +4941,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		if (cause == -1) {
 			/* other causes */
 			msix_vector |= IXGBE_IVAR_ALLOC_VAL;
@@ -4921,6 +4997,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		if (cause == -1) {
 			/* other causes */
 			index = (intr_alloc_entry & 1) * 8;
@@ -4971,6 +5049,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		if (cause == -1) {
 			/* other causes */
 			index = (intr_alloc_entry & 1) * 8;
@@ -5014,6 +5094,8 @@
 
 		case ixgbe_mac_82599EB:
 		case ixgbe_mac_X540:
+		case ixgbe_mac_X550:
+		case ixgbe_mac_X550EM_x:
 			return (sw_rx_index * 2);
 
 		default:
@@ -5030,6 +5112,8 @@
 
 		case ixgbe_mac_82599EB:
 		case ixgbe_mac_X540:
+		case ixgbe_mac_X550:
+		case ixgbe_mac_X550EM_x:
 			if (ixgbe->num_rx_groups > 32) {
 				hw_rx_index = (sw_rx_index /
 				    rx_ring_per_group) * 2 +
@@ -5135,6 +5219,8 @@
 
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
 		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);
