|
@@ -2507,6 +2507,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
|
|
|
|
|
|
bp->fw_wr_seq++;
|
|
|
msg_data |= bp->fw_wr_seq;
|
|
|
+ bp->fw_last_msg = msg_data;
|
|
|
|
|
|
bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
|
|
|
|
|
@@ -4000,8 +4001,23 @@ bnx2_setup_wol(struct bnx2 *bp)
|
|
|
wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
|
|
|
}
|
|
|
|
|
|
- if (!(bp->flags & BNX2_FLAG_NO_WOL))
|
|
|
- bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 1, 0);
|
|
|
+ if (!(bp->flags & BNX2_FLAG_NO_WOL)) {
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ wol_msg |= BNX2_DRV_MSG_DATA_WAIT3;
|
|
|
+ if (bp->fw_last_msg || BNX2_CHIP(bp) != BNX2_CHIP_5709) {
|
|
|
+ bnx2_fw_sync(bp, wol_msg, 1, 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ /* Tell firmware not to power down the PHY yet, otherwise
|
|
|
+ * the chip will take a long time to respond to MMIO reads.
|
|
|
+ */
|
|
|
+ val = bnx2_shmem_rd(bp, BNX2_PORT_FEATURE);
|
|
|
+ bnx2_shmem_wr(bp, BNX2_PORT_FEATURE,
|
|
|
+ val | BNX2_PORT_FEATURE_ASF_ENABLED);
|
|
|
+ bnx2_fw_sync(bp, wol_msg, 1, 0);
|
|
|
+ bnx2_shmem_wr(bp, BNX2_PORT_FEATURE, val);
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -4033,9 +4049,22 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
|
|
|
|
|
|
if (bp->wol)
|
|
|
pci_set_power_state(bp->pdev, PCI_D3hot);
|
|
|
- } else {
|
|
|
- pci_set_power_state(bp->pdev, PCI_D3hot);
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+ if (!bp->fw_last_msg && BNX2_CHIP(bp) == BNX2_CHIP_5709) {
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ /* Tell firmware not to power down the PHY yet,
|
|
|
+ * otherwise the other port may not respond to
|
|
|
+ * MMIO reads.
|
|
|
+ */
|
|
|
+ val = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
|
|
|
+ val &= ~BNX2_CONDITION_PM_STATE_MASK;
|
|
|
+ val |= BNX2_CONDITION_PM_STATE_UNPREP;
|
|
|
+ bnx2_shmem_wr(bp, BNX2_BC_STATE_CONDITION, val);
|
|
|
}
|
|
|
+ pci_set_power_state(bp->pdev, PCI_D3hot);
|
|
|
|
|
|
/* No more memory access after this point until
|
|
|
* device is brought back to D0.
|