diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sky2.c | 34 | ||||
-rw-r--r-- | drivers/net/sky2.h | 3 |
2 files changed, 30 insertions, 7 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 76038bb..a6ccd11 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2435,13 +2435,26 @@ static void sky2_hw_intr(struct sky2_hw *hw) if (status & Y2_IS_PCI_EXP) { /* PCI-Express uncorrectable Error occurred */ - int pos = pci_find_aer_capability(hw->pdev); + int aer = pci_find_aer_capability(hw->pdev); u32 err; - pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err); + if (aer) { + pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS, + &err); + pci_cleanup_aer_uncorrect_error_status(pdev); + } else { + /* Either AER not configured, or not working + * because of bad MMCONFIG, so just do recover + * manually. + */ + err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); + sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, + 0xfffffffful); + } + if (net_ratelimit()) dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err); - pci_cleanup_aer_uncorrect_error_status(pdev); + } if (status & Y2_HWE_L1_MASK) @@ -2799,9 +2812,18 @@ static void sky2_reset(struct sky2_hw *hw) 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 (pci_find_aer_capability(pdev)) { + /* Check for advanced error reporting */ + pci_cleanup_aer_uncorrect_error_status(pdev); + pci_cleanup_aer_correct_error_status(pdev); + } else { + dev_warn(&pdev->dev, + "PCI Express Advanced Error Reporting" + " not configured or MMCONFIG problem?\n"); + + sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, + 0xfffffffful); + } /* If error bit is stuck on ignore it */ if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP) diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 49ee264..69525fd 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -247,7 +247,8 @@ enum csr_regs { B3_PA_CTRL = 0x01f0, B3_PA_TEST = 0x01f2, - Y2_CFG_SPC = 0x1c00, + Y2_CFG_SPC = 0x1c00, /* PCI config space region */ + Y2_CFG_AER = 0x1d00, /* PCI Advanced Error Report region */ }; /* B0_CTST 16 bit Control/Status register */ |