Commit 193f5122 authored by David S. Miller's avatar David S. Miller

Merge branch 'bnx2-kdump-fix'

Baoquan He says:

====================
bnx2: Wait for in-flight DMA to complete at probe stage

This is v2 post.

In commit 3e1be7ad ("bnx2: Reset device during driver initialization"),
firmware requesting code was moved from open stage to probe stage.
The reason is in kdump kernel hardware iommu need device be reset in
driver probe stage, otherwise those in-flight DMA from 1st kernel
will continue going and look up into the newly created io-page tables.
However bnx2 chip resetting involves firmware requesting issue, that
need be done in open stage.

Michale Chan suggested we can just wait for the old in-flight DMA to
complete at probe stage, then though without device resetting, we
don't need to worry the old in-flight DMA could continue looking up
the newly created io-page tables.

v1->v2:
    Michael suggested to wait for the in-flight DMA to complete at probe
    stage. So give up the old method of trying to reset chip at probe
    stage, take the new way accordingly.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7020637b 6df77862
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/aer.h> #include <linux/aer.h>
#include <linux/crash_dump.h>
#if IS_ENABLED(CONFIG_CNIC) #if IS_ENABLED(CONFIG_CNIC)
#define BCM_CNIC 1 #define BCM_CNIC 1
...@@ -4764,15 +4765,16 @@ bnx2_setup_msix_tbl(struct bnx2 *bp) ...@@ -4764,15 +4765,16 @@ bnx2_setup_msix_tbl(struct bnx2 *bp)
BNX2_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR); BNX2_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR);
} }
static int static void
bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) bnx2_wait_dma_complete(struct bnx2 *bp)
{ {
u32 val; u32 val;
int i, rc = 0; int i;
u8 old_port;
/* 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) || if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) ||
(BNX2_CHIP(bp) == BNX2_CHIP_5708)) { (BNX2_CHIP(bp) == BNX2_CHIP_5708)) {
BNX2_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, BNX2_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
...@@ -4796,6 +4798,21 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) ...@@ -4796,6 +4798,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. */ /* 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); bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
...@@ -6361,6 +6378,10 @@ bnx2_open(struct net_device *dev) ...@@ -6361,6 +6378,10 @@ bnx2_open(struct net_device *dev)
struct bnx2 *bp = netdev_priv(dev); struct bnx2 *bp = netdev_priv(dev);
int rc; int rc;
rc = bnx2_request_firmware(bp);
if (rc < 0)
goto out;
netif_carrier_off(dev); netif_carrier_off(dev);
bnx2_disable_int(bp); bnx2_disable_int(bp);
...@@ -6429,6 +6450,7 @@ bnx2_open(struct net_device *dev) ...@@ -6429,6 +6450,7 @@ bnx2_open(struct net_device *dev)
bnx2_free_irq(bp); bnx2_free_irq(bp);
bnx2_free_mem(bp); bnx2_free_mem(bp);
bnx2_del_napi(bp); bnx2_del_napi(bp);
bnx2_release_firmware(bp);
goto out; goto out;
} }
...@@ -8575,12 +8597,15 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8575,12 +8597,15 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
rc = bnx2_request_firmware(bp); /*
if (rc < 0) * In-flight DMA from 1st kernel could continue going in kdump kernel.
goto error; * 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);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN); memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
...@@ -8613,7 +8638,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8613,7 +8638,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0; return 0;
error: error:
bnx2_release_firmware(bp);
pci_iounmap(pdev, bp->regview); pci_iounmap(pdev, bp->regview);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment