diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-03-21 13:57:06 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-21 16:00:51 -0500 |
commit | b9d64acc82c104df9e4d6b74cbb1af05a77b5d44 (patch) | |
tree | 796d6a43ea5f5e9c5d0ad591b9185c5bda261cf8 /drivers/net/skge.c | |
parent | 203babb650d0c99a8be08f479d4a05d420988d89 (diff) |
[PATCH] skge: handle pci errors better
When a PCI error occurs, try and report more info.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 7f8e8dd0fc6..0325fbceb35 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -2764,17 +2764,6 @@ static void skge_mac_parity(struct skge_hw *hw, int port) | |||
2764 | ? GMF_CLI_TX_FC : GMF_CLI_TX_PE); | 2764 | ? GMF_CLI_TX_FC : GMF_CLI_TX_PE); |
2765 | } | 2765 | } |
2766 | 2766 | ||
2767 | static void skge_pci_clear(struct skge_hw *hw) | ||
2768 | { | ||
2769 | u16 status; | ||
2770 | |||
2771 | pci_read_config_word(hw->pdev, PCI_STATUS, &status); | ||
2772 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
2773 | pci_write_config_word(hw->pdev, PCI_STATUS, | ||
2774 | status | PCI_STATUS_ERROR_BITS); | ||
2775 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
2776 | } | ||
2777 | |||
2778 | static void skge_mac_intr(struct skge_hw *hw, int port) | 2767 | static void skge_mac_intr(struct skge_hw *hw, int port) |
2779 | { | 2768 | { |
2780 | if (hw->chip_id == CHIP_ID_GENESIS) | 2769 | if (hw->chip_id == CHIP_ID_GENESIS) |
@@ -2816,23 +2805,39 @@ static void skge_error_irq(struct skge_hw *hw) | |||
2816 | if (hwstatus & IS_M2_PAR_ERR) | 2805 | if (hwstatus & IS_M2_PAR_ERR) |
2817 | skge_mac_parity(hw, 1); | 2806 | skge_mac_parity(hw, 1); |
2818 | 2807 | ||
2819 | if (hwstatus & IS_R1_PAR_ERR) | 2808 | if (hwstatus & IS_R1_PAR_ERR) { |
2809 | printk(KERN_ERR PFX "%s: receive queue parity error\n", | ||
2810 | hw->dev[0]->name); | ||
2820 | skge_write32(hw, B0_R1_CSR, CSR_IRQ_CL_P); | 2811 | skge_write32(hw, B0_R1_CSR, CSR_IRQ_CL_P); |
2812 | } | ||
2821 | 2813 | ||
2822 | if (hwstatus & IS_R2_PAR_ERR) | 2814 | if (hwstatus & IS_R2_PAR_ERR) { |
2815 | printk(KERN_ERR PFX "%s: receive queue parity error\n", | ||
2816 | hw->dev[1]->name); | ||
2823 | skge_write32(hw, B0_R2_CSR, CSR_IRQ_CL_P); | 2817 | skge_write32(hw, B0_R2_CSR, CSR_IRQ_CL_P); |
2818 | } | ||
2824 | 2819 | ||
2825 | if (hwstatus & (IS_IRQ_MST_ERR|IS_IRQ_STAT)) { | 2820 | if (hwstatus & (IS_IRQ_MST_ERR|IS_IRQ_STAT)) { |
2826 | printk(KERN_ERR PFX "hardware error detected (status 0x%x)\n", | 2821 | u16 pci_status, pci_cmd; |
2827 | hwstatus); | 2822 | |
2823 | pci_read_config_word(hw->pdev, PCI_COMMAND, &pci_cmd); | ||
2824 | pci_read_config_word(hw->pdev, PCI_STATUS, &pci_status); | ||
2828 | 2825 | ||
2829 | skge_pci_clear(hw); | 2826 | printk(KERN_ERR PFX "%s: PCI error cmd=%#x status=%#x\n", |
2827 | pci_name(hw->pdev), pci_cmd, pci_status); | ||
2828 | |||
2829 | /* Write the error bits back to clear them. */ | ||
2830 | pci_status &= PCI_STATUS_ERROR_BITS; | ||
2831 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
2832 | pci_write_config_word(hw->pdev, PCI_COMMAND, | ||
2833 | pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY); | ||
2834 | pci_write_config_word(hw->pdev, PCI_STATUS, pci_status); | ||
2835 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
2830 | 2836 | ||
2831 | /* if error still set then just ignore it */ | 2837 | /* if error still set then just ignore it */ |
2832 | hwstatus = skge_read32(hw, B0_HWE_ISRC); | 2838 | hwstatus = skge_read32(hw, B0_HWE_ISRC); |
2833 | if (hwstatus & IS_IRQ_STAT) { | 2839 | if (hwstatus & IS_IRQ_STAT) { |
2834 | pr_debug("IRQ status %x: still set ignoring hardware errors\n", | 2840 | printk(KERN_INFO PFX "unable to clear error (so ignoring them)\n"); |
2835 | hwstatus); | ||
2836 | hw->intr_mask &= ~IS_HW_ERR; | 2841 | hw->intr_mask &= ~IS_HW_ERR; |
2837 | } | 2842 | } |
2838 | } | 2843 | } |
@@ -2998,7 +3003,7 @@ static const char *skge_board_name(const struct skge_hw *hw) | |||
2998 | static int skge_reset(struct skge_hw *hw) | 3003 | static int skge_reset(struct skge_hw *hw) |
2999 | { | 3004 | { |
3000 | u32 reg; | 3005 | u32 reg; |
3001 | u16 ctst; | 3006 | u16 ctst, pci_status; |
3002 | u8 t8, mac_cfg, pmd_type, phy_type; | 3007 | u8 t8, mac_cfg, pmd_type, phy_type; |
3003 | int i; | 3008 | int i; |
3004 | 3009 | ||
@@ -3009,8 +3014,13 @@ static int skge_reset(struct skge_hw *hw) | |||
3009 | skge_write8(hw, B0_CTST, CS_RST_CLR); | 3014 | skge_write8(hw, B0_CTST, CS_RST_CLR); |
3010 | 3015 | ||
3011 | /* clear PCI errors, if any */ | 3016 | /* clear PCI errors, if any */ |
3012 | skge_pci_clear(hw); | 3017 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
3018 | skge_write8(hw, B2_TST_CTRL2, 0); | ||
3013 | 3019 | ||
3020 | pci_read_config_word(hw->pdev, PCI_STATUS, &pci_status); | ||
3021 | pci_write_config_word(hw->pdev, PCI_STATUS, | ||
3022 | pci_status | PCI_STATUS_ERROR_BITS); | ||
3023 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
3014 | skge_write8(hw, B0_CTST, CS_MRST_CLR); | 3024 | skge_write8(hw, B0_CTST, CS_MRST_CLR); |
3015 | 3025 | ||
3016 | /* restore CLK_RUN bits (for Yukon-Lite) */ | 3026 | /* restore CLK_RUN bits (for Yukon-Lite) */ |
@@ -3377,7 +3387,6 @@ static void __devexit skge_remove(struct pci_dev *pdev) | |||
3377 | 3387 | ||
3378 | skge_write32(hw, B0_IMSK, 0); | 3388 | skge_write32(hw, B0_IMSK, 0); |
3379 | skge_write16(hw, B0_LED, LED_STAT_OFF); | 3389 | skge_write16(hw, B0_LED, LED_STAT_OFF); |
3380 | skge_pci_clear(hw); | ||
3381 | skge_write8(hw, B0_CTST, CS_RST_SET); | 3390 | skge_write8(hw, B0_CTST, CS_RST_SET); |
3382 | 3391 | ||
3383 | tasklet_kill(&hw->ext_tasklet); | 3392 | tasklet_kill(&hw->ext_tasklet); |