Commit cf06ffb4 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Jeff Garzik

sky2: handle advanced error recovery config issues

The PCI AER support may not work for a couple of reasons.
It may not be configured into the kernel or there may be a BIOS
bug that prevents MMCONFIG from working.  If MMCONFIG doesn't work
then the PCI registers that control AER will not be accessible via
pci_read_config functions; luckly there is another window to access
PCI space in the device, so use that.
Signed-off-by: default avatarStephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent ab1a1456
......@@ -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)
......
......@@ -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 */
......
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