e1000: Fix Quadport Wake on LAN


Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: John Ronciak <john.ronciak@intel.com>
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 658f36a..a187827 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -242,6 +242,7 @@
 	uint32_t rx_buffer_len;
 	uint32_t part_num;
 	uint32_t wol;
+	uint32_t ksp3_port_a;
 	uint32_t smartspeed;
 	uint32_t en_mng_pt;
 	uint16_t link_speed;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index f7e81e9..f1b9cf4 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1632,10 +1632,26 @@
 	case E1000_DEV_ID_82546EB_QUAD_COPPER:
 	case E1000_DEV_ID_82545EM_FIBER:
 	case E1000_DEV_ID_82545EM_COPPER:
+	case E1000_DEV_ID_82546GB_QUAD_COPPER:
 		wol->supported = 0;
 		wol->wolopts   = 0;
 		return;
 
+	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
+		/* device id 10B5 port-A supports wol */
+		if (!adapter->ksp3_port_a) {
+			wol->supported = 0;
+			return;
+		}
+		/* KSP3 does not suppport UCAST wake-ups for any interface */
+		wol->supported = WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
+
+		if (adapter->wol & E1000_WUFC_EX)
+			DPRINTK(DRV, ERR, "Interface does not support "
+		        "directed (unicast) frame wake-up packets\n");
+		wol->wolopts = 0;
+		goto do_defaults;
+
 	case E1000_DEV_ID_82546EB_FIBER:
 	case E1000_DEV_ID_82546GB_FIBER:
 	case E1000_DEV_ID_82571EB_FIBER:
@@ -1650,8 +1666,9 @@
 	default:
 		wol->supported = WAKE_UCAST | WAKE_MCAST |
 				 WAKE_BCAST | WAKE_MAGIC;
-
 		wol->wolopts = 0;
+
+do_defaults:
 		if (adapter->wol & E1000_WUFC_EX)
 			wol->wolopts |= WAKE_UCAST;
 		if (adapter->wol & E1000_WUFC_MC)
@@ -1676,10 +1693,22 @@
 	case E1000_DEV_ID_82543GC_COPPER:
 	case E1000_DEV_ID_82544EI_FIBER:
 	case E1000_DEV_ID_82546EB_QUAD_COPPER:
+	case E1000_DEV_ID_82546GB_QUAD_COPPER:
 	case E1000_DEV_ID_82545EM_FIBER:
 	case E1000_DEV_ID_82545EM_COPPER:
 		return wol->wolopts ? -EOPNOTSUPP : 0;
 
+	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
+		/* device id 10B5 port-A supports wol */
+		if (!adapter->ksp3_port_a)
+			return wol->wolopts ? -EOPNOTSUPP : 0;
+
+		if (wol->wolopts & WAKE_UCAST) {
+			DPRINTK(DRV, ERR, "Interface does not support "
+		        "directed (unicast) frame wake-up packets\n");
+			return -EOPNOTSUPP;
+		}
+
 	case E1000_DEV_ID_82546EB_FIBER:
 	case E1000_DEV_ID_82546GB_FIBER:
 	case E1000_DEV_ID_82571EB_FIBER:
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index a525c95..aad5373 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -651,6 +651,7 @@
 	unsigned long mmio_start, mmio_len;
 
 	static int cards_found = 0;
+	static int e1000_ksp3_port_a = 0; /* global ksp3 port a indication */
 	int i, err, pci_using_dac;
 	uint16_t eeprom_data;
 	uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
@@ -743,6 +744,15 @@
 	if ((err = e1000_check_phy_reset_block(&adapter->hw)))
 		DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
 
+	/* if ksp3, indicate if it's port a being setup */
+	if (pdev->device == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 && 
+			e1000_ksp3_port_a == 0) 
+		adapter->ksp3_port_a = 1;
+	e1000_ksp3_port_a++;
+	/* Reset for multiple KP3 adapters */
+	if (e1000_ksp3_port_a == 4)
+		e1000_ksp3_port_a = 0;
+
 	if (adapter->hw.mac_type >= e1000_82543) {
 		netdev->features = NETIF_F_SG |
 				   NETIF_F_HW_CSUM |