diff options
Diffstat (limited to 'drivers/net/sky2.c')
| -rw-r--r-- | drivers/net/sky2.c | 55 | 
1 files changed, 45 insertions, 10 deletions
| diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index ab36a7460a26..380bb59f3517 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -2066,6 +2066,27 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port) | |||
| 2066 | } | 2066 | } | 
| 2067 | } | 2067 | } | 
| 2068 | 2068 | ||
| 2069 | /* This should never happen it is a fatal situation */ | ||
| 2070 | static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, | ||
| 2071 | const char *rxtx, u32 mask) | ||
| 2072 | { | ||
| 2073 | struct net_device *dev = hw->dev[port]; | ||
| 2074 | struct sky2_port *sky2 = netdev_priv(dev); | ||
| 2075 | u32 imask; | ||
| 2076 | |||
| 2077 | printk(KERN_ERR PFX "%s: %s descriptor error (hardware problem)\n", | ||
| 2078 | dev ? dev->name : "<not registered>", rxtx); | ||
| 2079 | |||
| 2080 | imask = sky2_read32(hw, B0_IMSK); | ||
| 2081 | imask &= ~mask; | ||
| 2082 | sky2_write32(hw, B0_IMSK, imask); | ||
| 2083 | |||
| 2084 | if (dev) { | ||
| 2085 | spin_lock(&sky2->phy_lock); | ||
| 2086 | sky2_link_down(sky2); | ||
| 2087 | spin_unlock(&sky2->phy_lock); | ||
| 2088 | } | ||
| 2089 | } | ||
| 2069 | 2090 | ||
| 2070 | static int sky2_poll(struct net_device *dev0, int *budget) | 2091 | static int sky2_poll(struct net_device *dev0, int *budget) | 
| 2071 | { | 2092 | { | 
| @@ -2074,20 +2095,34 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
| 2074 | int work_done = 0; | 2095 | int work_done = 0; | 
| 2075 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); | 2096 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); | 
| 2076 | 2097 | ||
| 2077 | if (status & Y2_IS_HW_ERR) | 2098 | if (unlikely(status & ~Y2_IS_STAT_BMU)) { | 
| 2078 | sky2_hw_intr(hw); | 2099 | if (status & Y2_IS_HW_ERR) | 
| 2100 | sky2_hw_intr(hw); | ||
| 2101 | |||
| 2102 | if (status & Y2_IS_IRQ_PHY1) | ||
| 2103 | sky2_phy_intr(hw, 0); | ||
| 2079 | 2104 | ||
| 2080 | if (status & Y2_IS_IRQ_PHY1) | 2105 | if (status & Y2_IS_IRQ_PHY2) | 
| 2081 | sky2_phy_intr(hw, 0); | 2106 | sky2_phy_intr(hw, 1); | 
| 2082 | 2107 | ||
| 2083 | if (status & Y2_IS_IRQ_PHY2) | 2108 | if (status & Y2_IS_IRQ_MAC1) | 
| 2084 | sky2_phy_intr(hw, 1); | 2109 | sky2_mac_intr(hw, 0); | 
| 2085 | 2110 | ||
| 2086 | if (status & Y2_IS_IRQ_MAC1) | 2111 | if (status & Y2_IS_IRQ_MAC2) | 
| 2087 | sky2_mac_intr(hw, 0); | 2112 | sky2_mac_intr(hw, 1); | 
| 2088 | 2113 | ||
| 2089 | if (status & Y2_IS_IRQ_MAC2) | 2114 | if (status & Y2_IS_CHK_RX1) | 
| 2090 | sky2_mac_intr(hw, 1); | 2115 | sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1); | 
| 2116 | |||
| 2117 | if (status & Y2_IS_CHK_RX2) | ||
| 2118 | sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2); | ||
| 2119 | |||
| 2120 | if (status & Y2_IS_CHK_TXA1) | ||
| 2121 | sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1); | ||
| 2122 | |||
| 2123 | if (status & Y2_IS_CHK_TXA2) | ||
| 2124 | sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); | ||
| 2125 | } | ||
| 2091 | 2126 | ||
| 2092 | if (status & Y2_IS_STAT_BMU) { | 2127 | if (status & Y2_IS_STAT_BMU) { | 
| 2093 | work_done = sky2_status_intr(hw, work_limit); | 2128 | work_done = sky2_status_intr(hw, work_limit); | 
