提交 1e5f1283 编写于 作者: S Stephen Hemminger

sky2: status irq hang fix

The status interrupt flag should be cleared before processing,
not afterwards to avoid race. Need to process in poll routine
even if no new interrupt status. This is a normal occurrence when
more than 64 frames (NAPI weight) are processed in one poll routine.
Signed-off-by: NStephen Hemminger <shemminger@osdl.org>
上级 d3240312
......@@ -2105,45 +2105,42 @@ static int sky2_poll(struct net_device *dev0, int *budget)
int work_done = 0;
u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
if (unlikely(status & ~Y2_IS_STAT_BMU)) {
if (status & Y2_IS_HW_ERR)
sky2_hw_intr(hw);
if (status & Y2_IS_HW_ERR)
sky2_hw_intr(hw);
if (status & Y2_IS_IRQ_PHY1)
sky2_phy_intr(hw, 0);
if (status & Y2_IS_IRQ_PHY1)
sky2_phy_intr(hw, 0);
if (status & Y2_IS_IRQ_PHY2)
sky2_phy_intr(hw, 1);
if (status & Y2_IS_IRQ_PHY2)
sky2_phy_intr(hw, 1);
if (status & Y2_IS_IRQ_MAC1)
sky2_mac_intr(hw, 0);
if (status & Y2_IS_IRQ_MAC1)
sky2_mac_intr(hw, 0);
if (status & Y2_IS_IRQ_MAC2)
sky2_mac_intr(hw, 1);
if (status & Y2_IS_IRQ_MAC2)
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_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_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_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_CHK_TXA2)
sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
if (status & Y2_IS_STAT_BMU) {
work_done = sky2_status_intr(hw, work_limit);
*budget -= work_done;
dev0->quota -= work_done;
if (status & Y2_IS_STAT_BMU)
sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
if (work_done >= work_limit)
return 1;
work_done = sky2_status_intr(hw, work_limit);
*budget -= work_done;
dev0->quota -= work_done;
sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
}
if (work_done >= work_limit)
return 1;
mod_timer(&hw->idle_timer, jiffies + HZ);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册