aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sky2.c55
-rw-r--r--drivers/net/sky2.h6
2 files changed, 49 insertions, 12 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 */
2070static 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
2070static int sky2_poll(struct net_device *dev0, int *budget) 2091static 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);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 50e9f7d38bf3..d63cd5a1b71c 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -279,8 +279,10 @@ enum {
279 Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */ 279 Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */
280 280
281 Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU, 281 Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU,
282 Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1, 282 Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1
283 Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2, 283 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1,
284 Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2
285 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2,
284}; 286};
285 287
286/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ 288/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */