aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-11-05 18:52:13 -0500
committerJeff Garzik <jeff@garzik.org>2007-11-10 04:25:09 -0500
commitcf06ffb4df5314d240a002e3e1c63722e9362070 (patch)
tree2c96afb706f9a87129c95f2631aeab7d21acd6bb
parentab1a145638addee40587daf12c98ec6a30029f0a (diff)
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>
-rw-r--r--drivers/net/sky2.c34
-rw-r--r--drivers/net/sky2.h3
2 files changed, 30 insertions, 7 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 76038bbeb50e..a6ccd11574d0 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2435,13 +2435,26 @@ static void sky2_hw_intr(struct sky2_hw *hw)
2435 2435
2436 if (status & Y2_IS_PCI_EXP) { 2436 if (status & Y2_IS_PCI_EXP) {
2437 /* PCI-Express uncorrectable Error occurred */ 2437 /* PCI-Express uncorrectable Error occurred */
2438 int pos = pci_find_aer_capability(hw->pdev); 2438 int aer = pci_find_aer_capability(hw->pdev);
2439 u32 err; 2439 u32 err;
2440 2440
2441 pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err); 2441 if (aer) {
2442 pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS,
2443 &err);
2444 pci_cleanup_aer_uncorrect_error_status(pdev);
2445 } else {
2446 /* Either AER not configured, or not working
2447 * because of bad MMCONFIG, so just do recover
2448 * manually.
2449 */
2450 err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
2451 sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
2452 0xfffffffful);
2453 }
2454
2442 if (net_ratelimit()) 2455 if (net_ratelimit())
2443 dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err); 2456 dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
2444 pci_cleanup_aer_uncorrect_error_status(pdev); 2457
2445 } 2458 }
2446 2459
2447 if (status & Y2_HWE_L1_MASK) 2460 if (status & Y2_HWE_L1_MASK)
@@ -2799,9 +2812,18 @@ static void sky2_reset(struct sky2_hw *hw)
2799 2812
2800 cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); 2813 cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
2801 if (cap) { 2814 if (cap) {
2802 /* Check for advanced error reporting */ 2815 if (pci_find_aer_capability(pdev)) {
2803 pci_cleanup_aer_uncorrect_error_status(pdev); 2816 /* Check for advanced error reporting */
2804 pci_cleanup_aer_correct_error_status(pdev); 2817 pci_cleanup_aer_uncorrect_error_status(pdev);
2818 pci_cleanup_aer_correct_error_status(pdev);
2819 } else {
2820 dev_warn(&pdev->dev,
2821 "PCI Express Advanced Error Reporting"
2822 " not configured or MMCONFIG problem?\n");
2823
2824 sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
2825 0xfffffffful);
2826 }
2805 2827
2806 /* If error bit is stuck on ignore it */ 2828 /* If error bit is stuck on ignore it */
2807 if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP) 2829 if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 49ee264064ab..69525fd7908d 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -247,7 +247,8 @@ enum csr_regs {
247 B3_PA_CTRL = 0x01f0, 247 B3_PA_CTRL = 0x01f0,
248 B3_PA_TEST = 0x01f2, 248 B3_PA_TEST = 0x01f2,
249 249
250 Y2_CFG_SPC = 0x1c00, 250 Y2_CFG_SPC = 0x1c00, /* PCI config space region */
251 Y2_CFG_AER = 0x1d00, /* PCI Advanced Error Report region */
251}; 252};
252 253
253/* B0_CTST 16 bit Control/Status register */ 254/* B0_CTST 16 bit Control/Status register */