diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-08-29 15:58:14 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:50:53 -0400 |
commit | 555382cbfc6d2187b53888190755e56f52308cd6 (patch) | |
tree | 70ffd0257aff8a18b721f813a05ef15cf63f2f48 | |
parent | 8c4c00f3710f9e5653ed465e88271664f3163930 (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>
-rw-r--r-- | drivers/net/sky2.c | 47 | ||||
-rw-r--r-- | drivers/net/sky2.h | 41 |
2 files changed, 27 insertions, 61 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 | ||
2422 | static void sky2_hw_intr(struct sky2_hw *hw) | 2423 | static 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 | ||
2776 | static void sky2_reset(struct sky2_hw *hw) | 2772 | static 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); |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 3d4f1903d62c..6f5e162709b6 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -18,14 +18,6 @@ enum { | |||
18 | PCI_CFG_REG_1 = 0x94, | 18 | PCI_CFG_REG_1 = 0x94, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | enum { | ||
22 | PEX_DEV_CAP = 0xe4, | ||
23 | PEX_DEV_CTRL = 0xe8, | ||
24 | PEX_DEV_STA = 0xea, | ||
25 | PEX_LNK_STAT = 0xf2, | ||
26 | PEX_UNC_ERR_STAT= 0x104, | ||
27 | }; | ||
28 | |||
29 | /* Yukon-2 */ | 21 | /* Yukon-2 */ |
30 | enum pci_dev_reg_1 { | 22 | enum pci_dev_reg_1 { |
31 | PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */ | 23 | PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */ |
@@ -151,38 +143,6 @@ enum pci_cfg_reg1 { | |||
151 | PCI_STATUS_REC_TARGET_ABORT | \ | 143 | PCI_STATUS_REC_TARGET_ABORT | \ |
152 | PCI_STATUS_PARITY) | 144 | PCI_STATUS_PARITY) |
153 | 145 | ||
154 | enum pex_dev_ctrl { | ||
155 | PEX_DC_MAX_RRS_MSK = 7<<12, /* Bit 14..12: Max. Read Request Size */ | ||
156 | PEX_DC_EN_NO_SNOOP = 1<<11,/* Enable No Snoop */ | ||
157 | PEX_DC_EN_AUX_POW = 1<<10,/* Enable AUX Power */ | ||
158 | PEX_DC_EN_PHANTOM = 1<<9, /* Enable Phantom Functions */ | ||
159 | PEX_DC_EN_EXT_TAG = 1<<8, /* Enable Extended Tag Field */ | ||
160 | PEX_DC_MAX_PLS_MSK = 7<<5, /* Bit 7.. 5: Max. Payload Size Mask */ | ||
161 | PEX_DC_EN_REL_ORD = 1<<4, /* Enable Relaxed Ordering */ | ||
162 | PEX_DC_EN_UNS_RQ_RP = 1<<3, /* Enable Unsupported Request Reporting */ | ||
163 | PEX_DC_EN_FAT_ER_RP = 1<<2, /* Enable Fatal Error Reporting */ | ||
164 | PEX_DC_EN_NFA_ER_RP = 1<<1, /* Enable Non-Fatal Error Reporting */ | ||
165 | PEX_DC_EN_COR_ER_RP = 1<<0, /* Enable Correctable Error Reporting */ | ||
166 | }; | ||
167 | #define PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK) | ||
168 | |||
169 | /* PEX_UNC_ERR_STAT PEX Uncorrectable Errors Status Register (Yukon-2) */ | ||
170 | enum pex_err { | ||
171 | PEX_UNSUP_REQ = 1<<20, /* Unsupported Request Error */ | ||
172 | |||
173 | PEX_MALFOR_TLP = 1<<18, /* Malformed TLP */ | ||
174 | |||
175 | PEX_UNEXP_COMP = 1<<16, /* Unexpected Completion */ | ||
176 | |||
177 | PEX_COMP_TO = 1<<14, /* Completion Timeout */ | ||
178 | PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */ | ||
179 | PEX_POIS_TLP = 1<<12, /* Poisoned TLP */ | ||
180 | |||
181 | PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */ | ||
182 | PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P), | ||
183 | }; | ||
184 | |||
185 | |||
186 | enum csr_regs { | 146 | enum csr_regs { |
187 | B0_RAP = 0x0000, | 147 | B0_RAP = 0x0000, |
188 | B0_CTST = 0x0004, | 148 | B0_CTST = 0x0004, |
@@ -419,7 +379,6 @@ enum { | |||
419 | Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2, | 379 | Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2, |
420 | 380 | ||
421 | Y2_HWE_ALL_MASK = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT | | 381 | Y2_HWE_ALL_MASK = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT | |
422 | Y2_IS_PCI_EXP | | ||
423 | Y2_HWE_L1_MASK | Y2_HWE_L2_MASK, | 382 | Y2_HWE_L1_MASK | Y2_HWE_L2_MASK, |
424 | }; | 383 | }; |
425 | 384 | ||