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 <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
ab1a145638
commit
cf06ffb4df
2 changed files with 30 additions and 7 deletions
|
@ -2435,13 +2435,26 @@ static void sky2_hw_intr(struct sky2_hw *hw)
|
||||||
|
|
||||||
if (status & Y2_IS_PCI_EXP) {
|
if (status & Y2_IS_PCI_EXP) {
|
||||||
/* PCI-Express uncorrectable Error occurred */
|
/* PCI-Express uncorrectable Error occurred */
|
||||||
int pos = pci_find_aer_capability(hw->pdev);
|
int aer = pci_find_aer_capability(hw->pdev);
|
||||||
u32 err;
|
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())
|
if (net_ratelimit())
|
||||||
dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
|
dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
|
||||||
pci_cleanup_aer_uncorrect_error_status(pdev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & Y2_HWE_L1_MASK)
|
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);
|
cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
|
||||||
if (cap) {
|
if (cap) {
|
||||||
/* Check for advanced error reporting */
|
if (pci_find_aer_capability(pdev)) {
|
||||||
pci_cleanup_aer_uncorrect_error_status(pdev);
|
/* Check for advanced error reporting */
|
||||||
pci_cleanup_aer_correct_error_status(pdev);
|
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 error bit is stuck on ignore it */
|
||||||
if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
|
if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
|
||||||
|
|
|
@ -247,7 +247,8 @@ enum csr_regs {
|
||||||
B3_PA_CTRL = 0x01f0,
|
B3_PA_CTRL = 0x01f0,
|
||||||
B3_PA_TEST = 0x01f2,
|
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 */
|
/* B0_CTST 16 bit Control/Status register */
|
||||||
|
|
Loading…
Add table
Reference in a new issue