#include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/pci.h>
+#include <linux/aer.h>
 #include <linux/ip.h>
 #include <net/ip.h>
 #include <linux/tcp.h>
 
 static void sky2_hw_intr(struct sky2_hw *hw)
 {
+       struct pci_dev *pdev = hw->pdev;
        u32 status = sky2_read32(hw, B0_HWE_ISRC);
+       u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
+
+       status &= hwmsk;
 
        if (status & Y2_IS_TIST_OV)
                sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
 
                pci_err = sky2_pci_read16(hw, PCI_STATUS);
                if (net_ratelimit())
-                       dev_err(&hw->pdev->dev, "PCI hardware error (0x%x)\n",
+                       dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
                                pci_err);
 
                sky2_pci_write16(hw, PCI_STATUS,
 
        if (status & Y2_IS_PCI_EXP) {
                /* PCI-Express uncorrectable Error occurred */
-               u32 pex_err;
-
-               pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
+               int pos = pci_find_aer_capability(hw->pdev);
+               u32 err;
 
+               pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err);
                if (net_ratelimit())
-                       dev_err(&hw->pdev->dev, "PCI Express error (0x%x)\n",
-                               pex_err);
-
-               /* clear the interrupt */
-               sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
-                                      0xffffffffUL);
-               if (pex_err & PEX_FATAL_ERRORS) {
-                       u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
-                       hwmsk &= ~Y2_IS_PCI_EXP;
-                       sky2_write32(hw, B0_HWE_IMSK, hwmsk);
-               }
+                       dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
+               pci_cleanup_aer_uncorrect_error_status(pdev);
        }
 
        if (status & Y2_HWE_L1_MASK)
 
 static void sky2_reset(struct sky2_hw *hw)
 {
+       struct pci_dev *pdev = hw->pdev;
        u16 status;
-       int i;
+       int i, cap;
+       u32 hwe_mask = Y2_HWE_ALL_MASK;
 
        /* disable ASF */
        if (hw->chip_id == CHIP_ID_YUKON_EX) {
 
        sky2_write8(hw, B0_CTST, CS_MRST_CLR);
 
-       /* clear any PEX errors */
-       if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
-               sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
+       cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+       if (cap) {
+               /* Check for advanced error reporting */
+               pci_cleanup_aer_uncorrect_error_status(pdev);
+               pci_cleanup_aer_correct_error_status(pdev);
 
+               /* If error bit is stuck on ignore it */
+               if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
+                       dev_info(&pdev->dev, "ignoring stuck error report bit\n");
+
+               else if (pci_enable_pcie_error_reporting(pdev))
+                       hwe_mask |= Y2_IS_PCI_EXP;
+       }
 
        sky2_power_on(hw);
 
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
        }
 
-       sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+       sky2_write32(hw, B0_HWE_IMSK, hwe_mask);
 
        for (i = 0; i < hw->ports; i++)
                sky2_gmac_reset(hw, i);
 
        PCI_CFG_REG_1   = 0x94,
 };
 
-enum {
-       PEX_DEV_CAP     = 0xe4,
-       PEX_DEV_CTRL    = 0xe8,
-       PEX_DEV_STA     = 0xea,
-       PEX_LNK_STAT    = 0xf2,
-       PEX_UNC_ERR_STAT= 0x104,
-};
-
 /* Yukon-2 */
 enum pci_dev_reg_1 {
        PCI_Y2_PIG_ENA   = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
                               PCI_STATUS_REC_TARGET_ABORT | \
                               PCI_STATUS_PARITY)
 
-enum pex_dev_ctrl {
-       PEX_DC_MAX_RRS_MSK      = 7<<12, /* Bit 14..12: Max. Read Request Size */
-       PEX_DC_EN_NO_SNOOP      = 1<<11,/* Enable No Snoop */
-       PEX_DC_EN_AUX_POW       = 1<<10,/* Enable AUX Power */
-       PEX_DC_EN_PHANTOM       = 1<<9, /* Enable Phantom Functions */
-       PEX_DC_EN_EXT_TAG       = 1<<8, /* Enable Extended Tag Field */
-       PEX_DC_MAX_PLS_MSK      = 7<<5, /* Bit  7.. 5:  Max. Payload Size Mask */
-       PEX_DC_EN_REL_ORD       = 1<<4, /* Enable Relaxed Ordering */
-       PEX_DC_EN_UNS_RQ_RP     = 1<<3, /* Enable Unsupported Request Reporting */
-       PEX_DC_EN_FAT_ER_RP     = 1<<2, /* Enable Fatal Error Reporting */
-       PEX_DC_EN_NFA_ER_RP     = 1<<1, /* Enable Non-Fatal Error Reporting */
-       PEX_DC_EN_COR_ER_RP     = 1<<0, /* Enable Correctable Error Reporting */
-};
-#define  PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
-
-/* PEX_UNC_ERR_STAT     PEX Uncorrectable Errors Status Register (Yukon-2) */
-enum pex_err {
-       PEX_UNSUP_REQ   = 1<<20, /* Unsupported Request Error */
-
-       PEX_MALFOR_TLP  = 1<<18, /* Malformed TLP */
-
-       PEX_UNEXP_COMP  = 1<<16, /* Unexpected Completion */
-
-       PEX_COMP_TO     = 1<<14, /* Completion Timeout */
-       PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */
-       PEX_POIS_TLP    = 1<<12, /* Poisoned TLP */
-
-       PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */
-       PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
-};
-
-
 enum csr_regs {
        B0_RAP          = 0x0000,
        B0_CTST         = 0x0004,
                          Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2,
 
        Y2_HWE_ALL_MASK = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT |
-                         Y2_IS_PCI_EXP |
                          Y2_HWE_L1_MASK | Y2_HWE_L2_MASK,
 };