]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bnx2: Wait for in-flight DMA to complete at probe stage
authorBaoquan He <bhe@redhat.com>
Sun, 13 Nov 2016 05:01:33 +0000 (13:01 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Nov 2016 09:11:36 +0000 (10:11 +0100)
[ Upstream commit 6df77862f63f389df3b1ad879738e04440d7385d ]

In-flight DMA from 1st kernel could continue going in kdump kernel.
New io-page table has been created before bnx2 does reset at open stage.
We have to wait for the in-flight DMA to complete to avoid it look up
into the newly created io-page table at probe stage.

Suggested-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: Baoquan He <bhe@redhat.com>
Acked-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/broadcom/bnx2.c

index 8fc3f3c137f87d2ac4fb0fc867acd50def69a03f..2c850a92ab1540e7f4a085e2a8f860956ae86f9e 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/firmware.h>
 #include <linux/log2.h>
 #include <linux/aer.h>
+#include <linux/crash_dump.h>
 
 #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
 #define BCM_CNIC 1
@@ -4759,15 +4760,16 @@ bnx2_setup_msix_tbl(struct bnx2 *bp)
        BNX2_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR);
 }
 
-static int
-bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
+static void
+bnx2_wait_dma_complete(struct bnx2 *bp)
 {
        u32 val;
-       int i, rc = 0;
-       u8 old_port;
+       int i;
 
-       /* Wait for the current PCI transaction to complete before
-        * issuing a reset. */
+       /*
+        * Wait for the current PCI transaction to complete before
+        * issuing a reset.
+        */
        if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) ||
            (BNX2_CHIP(bp) == BNX2_CHIP_5708)) {
                BNX2_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
@@ -4791,6 +4793,21 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
                }
        }
 
+       return;
+}
+
+
+static int
+bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
+{
+       u32 val;
+       int i, rc = 0;
+       u8 old_port;
+
+       /* Wait for the current PCI transaction to complete before
+        * issuing a reset. */
+       bnx2_wait_dma_complete(bp);
+
        /* Wait for the firmware to tell us it is ok to issue a reset. */
        bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
 
@@ -8575,6 +8592,15 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_drvdata(pdev, dev);
 
+       /*
+        * In-flight DMA from 1st kernel could continue going in kdump kernel.
+        * New io-page table has been created before bnx2 does reset at open stage.
+        * We have to wait for the in-flight DMA to complete to avoid it look up
+        * into the newly created io-page table.
+        */
+       if (is_kdump_kernel())
+               bnx2_wait_dma_complete(bp);
+
        memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);
 
        dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |