From cf06ffb4df5314d240a002e3e1c63722e9362070 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 5 Nov 2007 15:52:13 -0800 Subject: [PATCH] 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: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 34 ++++++++++++++++++++++++++++------ 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 */ -- 2.7.4