aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-05-08 15:11:31 -0700
committerStephen Hemminger <shemminger@osdl.org>2006-05-08 16:00:27 -0700
commite71ebd73276cc21efc74aba4118ef037cd32e50a (patch)
treef19a898ff09d4d78e3334b33c08c48a7bd77ced1 /drivers/net/sky2.c
parent01bd75645f94d49cb7ffd61022890166ce00ec2a (diff)
sky2: dont write status ring
It is more efficient not to write the status ring from the processor and just read the active portion. Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c21
1 files changed, 7 insertions, 14 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 940ed699a70..ea23da53677 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1865,35 +1865,28 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
static int sky2_status_intr(struct sky2_hw *hw, int to_do)
{
int work_done = 0;
+ u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
rmb();
- for(;;) {
+ while (hw->st_idx != hwidx) {
struct sky2_status_le *le = hw->st_le + hw->st_idx;
struct net_device *dev;
struct sky2_port *sky2;
struct sk_buff *skb;
u32 status;
u16 length;
- u8 link, opcode;
-
- opcode = le->opcode;
- if (!opcode)
- break;
- opcode &= ~HW_OWNER;
hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
- le->opcode = 0;
- link = le->link;
- BUG_ON(link >= 2);
- dev = hw->dev[link];
+ BUG_ON(le->link >= 2);
+ dev = hw->dev[le->link];
sky2 = netdev_priv(dev);
length = le->length;
status = le->status;
- switch (opcode) {
+ switch (le->opcode & ~HW_OWNER) {
case OP_RXSTAT:
skb = sky2_receive(sky2, length, status);
if (!skb)
@@ -1944,8 +1937,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
default:
if (net_ratelimit())
printk(KERN_WARNING PFX
- "unknown status opcode 0x%x\n", opcode);
- break;
+ "unknown status opcode 0x%x\n", le->opcode);
+ goto exit_loop;
}
}