tg3: Preserve DASH connectivity when WOL enabled

DASH firmware runs on the APE side of the chip, but it requires a few MAC
to be programmed correctly.

When WOL is enabled and management firmware is disabled, incoming
packets are evaluated and discarded at the chip's rule processor.
When management firmware is enabled, the hardware must be informed that
there are agents further up the stack that still use the incoming
frames.  Normally management firmware will configure the MAC correctly
on its own, but there can be cases where the setting could get clobbered
by the driver.  The first hunk of this patch preserves this setting.

The second hunk of this patch wipes out the driver present signature of
the APE memory space.  By doing so, the DASH firmware can assume
driver absent behavior.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e129a6a..e04cd98 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2156,8 +2156,14 @@
 			tw32(MAC_LED_CTRL, tp->led_ctrl);
 
 		if (pci_pme_capable(tp->pdev, state) &&
-		     (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
+		     (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
 			mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
+			if (((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+			    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) &&
+			    ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+			     (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)))
+				mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL;
+		}
 
 		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
 			mac_mode |= tp->mac_mode &
@@ -5562,6 +5568,13 @@
 			event = APE_EVENT_STATUS_STATE_START;
 			break;
 		case RESET_KIND_SHUTDOWN:
+			/* With the interface we are currently using,
+			 * APE does not track driver state.  Wiping
+			 * out the HOST SEGMENT SIGNATURE forces
+			 * the APE to assume OS absent status.
+			 */
+			tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0);
+
 			event = APE_EVENT_STATUS_STATE_UNLOAD;
 			break;
 		case RESET_KIND_SUSPEND: