summaryrefslogtreecommitdiff
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-05-17 14:37:06 -0700
committerJeff Garzik <jeff@garzik.org>2006-05-20 00:15:39 -0400
commit86fba6342dee30a1533b14da284d79e4eb66de26 (patch)
tree1ec4d7f2b874baa2f2548ed05ee4ab232b181c0f /drivers/net/sky2.c
parent86a31a759f2117816b8c78a049c41ead3ef9ef1c (diff)
[PATCH] sky2: force NAPI repoll if busy
If the status ring processing can't keep up with the incoming frames, it is more efficient to have NAPI keep scheduling the poll routine rather than causing another interrupt. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index bb185e5efa35..9729062d1fbb 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1919,6 +1919,12 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
}
}
+/* Is status ring empty or is there more to do? */
+static inline int sky2_more_work(const struct sky2_hw *hw)
+{
+ return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX));
+}
+
/* Process status response ring */
static int sky2_status_intr(struct sky2_hw *hw, int to_do)
{
@@ -2191,19 +2197,19 @@ static int sky2_poll(struct net_device *dev0, int *budget)
if (status & Y2_IS_CHK_TXA2)
sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
- if (status & Y2_IS_STAT_BMU)
- sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-
work_done = sky2_status_intr(hw, work_limit);
*budget -= work_done;
dev0->quota -= work_done;
- if (work_done >= work_limit)
+ if (status & Y2_IS_STAT_BMU)
+ sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+
+ if (sky2_more_work(hw))
return 1;
netif_rx_complete(dev0);
- status = sky2_read32(hw, B0_Y2_SP_LISR);
+ sky2_read32(hw, B0_Y2_SP_LISR);
return 0;
}