|
@@ -2477,8 +2477,7 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status)
|
|
|
static int sky2_poll(struct net_device *dev0, int *budget)
|
|
|
{
|
|
|
struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
|
|
|
- int work_limit = min(dev0->quota, *budget);
|
|
|
- int work_done = 0;
|
|
|
+ int work_done;
|
|
|
u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
|
|
|
|
|
|
if (unlikely(status & Y2_IS_ERROR))
|
|
@@ -2490,25 +2489,25 @@ static int sky2_poll(struct net_device *dev0, int *budget)
|
|
|
if (status & Y2_IS_IRQ_PHY2)
|
|
|
sky2_phy_intr(hw, 1);
|
|
|
|
|
|
- work_done = sky2_status_intr(hw, work_limit);
|
|
|
- if (work_done < work_limit) {
|
|
|
- /* Bug/Errata workaround?
|
|
|
- * Need to kick the TX irq moderation timer.
|
|
|
- */
|
|
|
- if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
|
|
|
- sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
|
|
|
- sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
|
|
|
- }
|
|
|
- netif_rx_complete(dev0);
|
|
|
+ work_done = sky2_status_intr(hw, min(dev0->quota, *budget));
|
|
|
+ *budget -= work_done;
|
|
|
+ dev0->quota -= work_done;
|
|
|
|
|
|
- /* end of interrupt, re-enables also acts as I/O synchronization */
|
|
|
- sky2_read32(hw, B0_Y2_SP_LISR);
|
|
|
- return 0;
|
|
|
- } else {
|
|
|
- *budget -= work_done;
|
|
|
- dev0->quota -= work_done;
|
|
|
+ /* More work? */
|
|
|
+ if (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX))
|
|
|
return 1;
|
|
|
+
|
|
|
+ /* Bug/Errata workaround?
|
|
|
+ * Need to kick the TX irq moderation timer.
|
|
|
+ */
|
|
|
+ if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
|
|
|
+ sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
|
|
|
+ sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
|
|
|
}
|
|
|
+ netif_rx_complete(dev0);
|
|
|
+
|
|
|
+ sky2_read32(hw, B0_Y2_SP_LISR);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static irqreturn_t sky2_intr(int irq, void *dev_id)
|