diff options
author | John Feeney <jfeeney@redhat.com> | 2010-08-22 13:45:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-23 00:09:03 -0400 |
commit | cd709aa90648195e5b5823fa90eb0b3fb0e78ee4 (patch) | |
tree | 58db107cfa29dbeb9948cc027a3619bbdc34125d /drivers | |
parent | 05532121da0728eaedac2a0a5c3cecad3a95d765 (diff) |
bnx2: Add PCI Advanced Error Reporting support.
Signed-off-by: John Feeney <jfeeney@redhat.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bnx2.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index e6a803f1c507..a0e02aa42214 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/cache.h> | 49 | #include <linux/cache.h> |
50 | #include <linux/firmware.h> | 50 | #include <linux/firmware.h> |
51 | #include <linux/log2.h> | 51 | #include <linux/log2.h> |
52 | #include <linux/aer.h> | ||
52 | 53 | ||
53 | #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) | 54 | #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) |
54 | #define BCM_CNIC 1 | 55 | #define BCM_CNIC 1 |
@@ -7890,6 +7891,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
7890 | int rc, i, j; | 7891 | int rc, i, j; |
7891 | u32 reg; | 7892 | u32 reg; |
7892 | u64 dma_mask, persist_dma_mask; | 7893 | u64 dma_mask, persist_dma_mask; |
7894 | int err; | ||
7893 | 7895 | ||
7894 | SET_NETDEV_DEV(dev, &pdev->dev); | 7896 | SET_NETDEV_DEV(dev, &pdev->dev); |
7895 | bp = netdev_priv(dev); | 7897 | bp = netdev_priv(dev); |
@@ -7925,6 +7927,14 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
7925 | goto err_out_disable; | 7927 | goto err_out_disable; |
7926 | } | 7928 | } |
7927 | 7929 | ||
7930 | /* AER (Advanced Error Reporting) hooks */ | ||
7931 | err = pci_enable_pcie_error_reporting(pdev); | ||
7932 | if (err) { | ||
7933 | dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed " | ||
7934 | "0x%x\n", err); | ||
7935 | /* non-fatal, continue */ | ||
7936 | } | ||
7937 | |||
7928 | pci_set_master(pdev); | 7938 | pci_set_master(pdev); |
7929 | pci_save_state(pdev); | 7939 | pci_save_state(pdev); |
7930 | 7940 | ||
@@ -8246,6 +8256,7 @@ err_out_unmap: | |||
8246 | } | 8256 | } |
8247 | 8257 | ||
8248 | err_out_release: | 8258 | err_out_release: |
8259 | pci_disable_pcie_error_reporting(pdev); | ||
8249 | pci_release_regions(pdev); | 8260 | pci_release_regions(pdev); |
8250 | 8261 | ||
8251 | err_out_disable: | 8262 | err_out_disable: |
@@ -8436,6 +8447,9 @@ bnx2_remove_one(struct pci_dev *pdev) | |||
8436 | kfree(bp->temp_stats_blk); | 8447 | kfree(bp->temp_stats_blk); |
8437 | 8448 | ||
8438 | free_netdev(dev); | 8449 | free_netdev(dev); |
8450 | |||
8451 | pci_disable_pcie_error_reporting(pdev); | ||
8452 | |||
8439 | pci_release_regions(pdev); | 8453 | pci_release_regions(pdev); |
8440 | pci_disable_device(pdev); | 8454 | pci_disable_device(pdev); |
8441 | pci_set_drvdata(pdev, NULL); | 8455 | pci_set_drvdata(pdev, NULL); |
@@ -8527,25 +8541,35 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev) | |||
8527 | { | 8541 | { |
8528 | struct net_device *dev = pci_get_drvdata(pdev); | 8542 | struct net_device *dev = pci_get_drvdata(pdev); |
8529 | struct bnx2 *bp = netdev_priv(dev); | 8543 | struct bnx2 *bp = netdev_priv(dev); |
8544 | pci_ers_result_t result; | ||
8545 | int err; | ||
8530 | 8546 | ||
8531 | rtnl_lock(); | 8547 | rtnl_lock(); |
8532 | if (pci_enable_device(pdev)) { | 8548 | if (pci_enable_device(pdev)) { |
8533 | dev_err(&pdev->dev, | 8549 | dev_err(&pdev->dev, |
8534 | "Cannot re-enable PCI device after reset\n"); | 8550 | "Cannot re-enable PCI device after reset\n"); |
8535 | rtnl_unlock(); | 8551 | result = PCI_ERS_RESULT_DISCONNECT; |
8536 | return PCI_ERS_RESULT_DISCONNECT; | 8552 | } else { |
8553 | pci_set_master(pdev); | ||
8554 | pci_restore_state(pdev); | ||
8555 | pci_save_state(pdev); | ||
8556 | |||
8557 | if (netif_running(dev)) { | ||
8558 | bnx2_set_power_state(bp, PCI_D0); | ||
8559 | bnx2_init_nic(bp, 1); | ||
8560 | } | ||
8561 | result = PCI_ERS_RESULT_RECOVERED; | ||
8537 | } | 8562 | } |
8538 | pci_set_master(pdev); | 8563 | rtnl_unlock(); |
8539 | pci_restore_state(pdev); | ||
8540 | pci_save_state(pdev); | ||
8541 | 8564 | ||
8542 | if (netif_running(dev)) { | 8565 | err = pci_cleanup_aer_uncorrect_error_status(pdev); |
8543 | bnx2_set_power_state(bp, PCI_D0); | 8566 | if (err) { |
8544 | bnx2_init_nic(bp, 1); | 8567 | dev_err(&pdev->dev, |
8568 | "pci_cleanup_aer_uncorrect_error_status failed 0x%0x\n", | ||
8569 | err); /* non-fatal, continue */ | ||
8545 | } | 8570 | } |
8546 | 8571 | ||
8547 | rtnl_unlock(); | 8572 | return result; |
8548 | return PCI_ERS_RESULT_RECOVERED; | ||
8549 | } | 8573 | } |
8550 | 8574 | ||
8551 | /** | 8575 | /** |