aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-08-29 15:58:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:50:53 -0400
commit555382cbfc6d2187b53888190755e56f52308cd6 (patch)
tree70ffd0257aff8a18b721f813a05ef15cf63f2f48 /drivers/net/sky2.c
parent8c4c00f3710f9e5653ed465e88271664f3163930 (diff)
sky2: advanced error reporting
Use the kernel interfaces for advanced error reporting. This should be cleaner and clear up errors on boot. For those systems with busted BIOS's that don't correctly support mmconfig, advanced error reporting will be disabled. The PCI registers for advanced error reporting start at 0x100 which is too large to be accessed by legacy functions. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 77bfcf0dda3b..b81d81746c2c 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -31,6 +31,7 @@
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/ethtool.h> 32#include <linux/ethtool.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/aer.h>
34#include <linux/ip.h> 35#include <linux/ip.h>
35#include <net/ip.h> 36#include <net/ip.h>
36#include <linux/tcp.h> 37#include <linux/tcp.h>
@@ -2421,7 +2422,11 @@ static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
2421 2422
2422static void sky2_hw_intr(struct sky2_hw *hw) 2423static void sky2_hw_intr(struct sky2_hw *hw)
2423{ 2424{
2425 struct pci_dev *pdev = hw->pdev;
2424 u32 status = sky2_read32(hw, B0_HWE_ISRC); 2426 u32 status = sky2_read32(hw, B0_HWE_ISRC);
2427 u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
2428
2429 status &= hwmsk;
2425 2430
2426 if (status & Y2_IS_TIST_OV) 2431 if (status & Y2_IS_TIST_OV)
2427 sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ); 2432 sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
@@ -2431,7 +2436,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
2431 2436
2432 pci_err = sky2_pci_read16(hw, PCI_STATUS); 2437 pci_err = sky2_pci_read16(hw, PCI_STATUS);
2433 if (net_ratelimit()) 2438 if (net_ratelimit())
2434 dev_err(&hw->pdev->dev, "PCI hardware error (0x%x)\n", 2439 dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
2435 pci_err); 2440 pci_err);
2436 2441
2437 sky2_pci_write16(hw, PCI_STATUS, 2442 sky2_pci_write16(hw, PCI_STATUS,
@@ -2440,22 +2445,13 @@ static void sky2_hw_intr(struct sky2_hw *hw)
2440 2445
2441 if (status & Y2_IS_PCI_EXP) { 2446 if (status & Y2_IS_PCI_EXP) {
2442 /* PCI-Express uncorrectable Error occurred */ 2447 /* PCI-Express uncorrectable Error occurred */
2443 u32 pex_err; 2448 int pos = pci_find_aer_capability(hw->pdev);
2444 2449 u32 err;
2445 pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
2446 2450
2451 pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err);
2447 if (net_ratelimit()) 2452 if (net_ratelimit())
2448 dev_err(&hw->pdev->dev, "PCI Express error (0x%x)\n", 2453 dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
2449 pex_err); 2454 pci_cleanup_aer_uncorrect_error_status(pdev);
2450
2451 /* clear the interrupt */
2452 sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
2453 0xffffffffUL);
2454 if (pex_err & PEX_FATAL_ERRORS) {
2455 u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
2456 hwmsk &= ~Y2_IS_PCI_EXP;
2457 sky2_write32(hw, B0_HWE_IMSK, hwmsk);
2458 }
2459 } 2455 }
2460 2456
2461 if (status & Y2_HWE_L1_MASK) 2457 if (status & Y2_HWE_L1_MASK)
@@ -2775,8 +2771,10 @@ static int __devinit sky2_init(struct sky2_hw *hw)
2775 2771
2776static void sky2_reset(struct sky2_hw *hw) 2772static void sky2_reset(struct sky2_hw *hw)
2777{ 2773{
2774 struct pci_dev *pdev = hw->pdev;
2778 u16 status; 2775 u16 status;
2779 int i; 2776 int i, cap;
2777 u32 hwe_mask = Y2_HWE_ALL_MASK;
2780 2778
2781 /* disable ASF */ 2779 /* disable ASF */
2782 if (hw->chip_id == CHIP_ID_YUKON_EX) { 2780 if (hw->chip_id == CHIP_ID_YUKON_EX) {
@@ -2800,10 +2798,19 @@ static void sky2_reset(struct sky2_hw *hw)
2800 2798
2801 sky2_write8(hw, B0_CTST, CS_MRST_CLR); 2799 sky2_write8(hw, B0_CTST, CS_MRST_CLR);
2802 2800
2803 /* clear any PEX errors */ 2801 cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
2804 if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) 2802 if (cap) {
2805 sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); 2803 /* Check for advanced error reporting */
2804 pci_cleanup_aer_uncorrect_error_status(pdev);
2805 pci_cleanup_aer_correct_error_status(pdev);
2806 2806
2807 /* If error bit is stuck on ignore it */
2808 if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
2809 dev_info(&pdev->dev, "ignoring stuck error report bit\n");
2810
2811 else if (pci_enable_pcie_error_reporting(pdev))
2812 hwe_mask |= Y2_IS_PCI_EXP;
2813 }
2807 2814
2808 sky2_power_on(hw); 2815 sky2_power_on(hw);
2809 2816
@@ -2855,7 +2862,7 @@ static void sky2_reset(struct sky2_hw *hw)
2855 sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53); 2862 sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
2856 } 2863 }
2857 2864
2858 sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK); 2865 sky2_write32(hw, B0_HWE_IMSK, hwe_mask);
2859 2866
2860 for (i = 0; i < hw->ports; i++) 2867 for (i = 0; i < hw->ports; i++)
2861 sky2_gmac_reset(hw, i); 2868 sky2_gmac_reset(hw, i);