Commit d257924e authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Jeff Garzik

[PATCH] sky2: handle all error irqs

The hardware has additional error trap interrupt bits.  I have never seen
them trigger, but if they do, it looks like this might be useful.
Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.rog>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 8f24664d
...@@ -2066,6 +2066,27 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port) ...@@ -2066,6 +2066,27 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
} }
} }
/* This should never happen it is a fatal situation */
static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port,
const char *rxtx, u32 mask)
{
struct net_device *dev = hw->dev[port];
struct sky2_port *sky2 = netdev_priv(dev);
u32 imask;
printk(KERN_ERR PFX "%s: %s descriptor error (hardware problem)\n",
dev ? dev->name : "<not registered>", rxtx);
imask = sky2_read32(hw, B0_IMSK);
imask &= ~mask;
sky2_write32(hw, B0_IMSK, imask);
if (dev) {
spin_lock(&sky2->phy_lock);
sky2_link_down(sky2);
spin_unlock(&sky2->phy_lock);
}
}
static int sky2_poll(struct net_device *dev0, int *budget) static int sky2_poll(struct net_device *dev0, int *budget)
{ {
...@@ -2074,6 +2095,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) ...@@ -2074,6 +2095,7 @@ static int sky2_poll(struct net_device *dev0, int *budget)
int work_done = 0; int work_done = 0;
u32 status = sky2_read32(hw, B0_Y2_SP_EISR); u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
if (unlikely(status & ~Y2_IS_STAT_BMU)) {
if (status & Y2_IS_HW_ERR) if (status & Y2_IS_HW_ERR)
sky2_hw_intr(hw); sky2_hw_intr(hw);
...@@ -2089,6 +2111,19 @@ static int sky2_poll(struct net_device *dev0, int *budget) ...@@ -2089,6 +2111,19 @@ static int sky2_poll(struct net_device *dev0, int *budget)
if (status & Y2_IS_IRQ_MAC2) if (status & Y2_IS_IRQ_MAC2)
sky2_mac_intr(hw, 1); sky2_mac_intr(hw, 1);
if (status & Y2_IS_CHK_RX1)
sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1);
if (status & Y2_IS_CHK_RX2)
sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2);
if (status & Y2_IS_CHK_TXA1)
sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1);
if (status & Y2_IS_CHK_TXA2)
sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
}
if (status & Y2_IS_STAT_BMU) { if (status & Y2_IS_STAT_BMU) {
work_done = sky2_status_intr(hw, work_limit); work_done = sky2_status_intr(hw, work_limit);
*budget -= work_done; *budget -= work_done;
......
...@@ -279,8 +279,10 @@ enum { ...@@ -279,8 +279,10 @@ enum {
Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */ Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */
Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU, Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU,
Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1, Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1
Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2, | Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1,
Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2
| Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2,
}; };
/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment