bnx2x: Add AER support (missing bits)
authorYuval Mintz <yuvalmin@broadcom.com>
Thu, 26 Dec 2013 07:57:08 +0000 (09:57 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 26 Dec 2013 18:38:21 +0000 (13:38 -0500)
This function adds several OS calls required to fully enable PCIe AER support -
pci_enable_pcie_error_reporting() and pci_cleanup_aer_uncorrect_error_status().

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

index 52019a90cd156d75ebdfaecbdf28e80f627cc760..dad67905f4e28f0a29f9ff0c601351f8e3dc9f65 100644 (file)
@@ -1546,6 +1546,7 @@ struct bnx2x {
 #define INTERRUPTS_ENABLED_FLAG                (1 << 23)
 #define BC_SUPPORTS_RMMOD_CMD          (1 << 24)
 #define HAS_PHYS_PORT_ID               (1 << 25)
+#define AER_ENABLED                    (1 << 26)
 
 #define BP_NOMCP(bp)                   ((bp)->flags & NO_MCP_FLAG)
 
index 591041379b27067d0777667acb544ad78e1f0a04..72973cc7ecbeb7f75ec5962eae9a654ef17ce7e3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/aer.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -12225,6 +12226,14 @@ static int bnx2x_set_coherency_mask(struct bnx2x *bp)
        return 0;
 }
 
+static void bnx2x_disable_pcie_error_reporting(struct bnx2x *bp)
+{
+       if (bp->flags & AER_ENABLED) {
+               pci_disable_pcie_error_reporting(bp->pdev);
+               bp->flags &= ~AER_ENABLED;
+       }
+}
+
 static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
                          struct net_device *dev, unsigned long board_type)
 {
@@ -12331,6 +12340,14 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
        /* clean indirect addresses */
        pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
                               PCICFG_VENDOR_ID_OFFSET);
+
+       /* AER (Advanced Error reporting) configuration */
+       rc = pci_enable_pcie_error_reporting(pdev);
+       if (!rc)
+               bp->flags |= AER_ENABLED;
+       else
+               BNX2X_DEV_INFO("Failed To configure PCIe AER [%d]\n", rc);
+
        /*
         * Clean the following indirect addresses for all functions since it
         * is not used by the driver.
@@ -12938,6 +12955,8 @@ static int bnx2x_init_one(struct pci_dev *pdev,
        return 0;
 
 init_one_exit:
+       bnx2x_disable_pcie_error_reporting(bp);
+
        if (bp->regview)
                iounmap(bp->regview);
 
@@ -13011,6 +13030,8 @@ static void __bnx2x_remove(struct pci_dev *pdev,
                pci_set_power_state(pdev, PCI_D3hot);
        }
 
+       bnx2x_disable_pcie_error_reporting(bp);
+
        if (bp->regview)
                iounmap(bp->regview);
 
@@ -13188,6 +13209,14 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
 
        rtnl_unlock();
 
+       /* If AER, perform cleanup of the PCIe registers */
+       if (bp->flags & AER_ENABLED) {
+               if (pci_cleanup_aer_uncorrect_error_status(pdev))
+                       BNX2X_ERR("pci_cleanup_aer_uncorrect_error_status failed\n");
+               else
+                       DP(NETIF_MSG_HW, "pci_cleanup_aer_uncorrect_error_status succeeded\n");
+       }
+
        return PCI_ERS_RESULT_RECOVERED;
 }