diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 47 |
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 | ||
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); |