Commit a2b89768 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Greg Kroah-Hartman

sky2: status ring race fix

patch ab5adecb in mainline.

The D-Link PCI-X board (and maybe others) can lie about status
ring entries. It seems it will update the register for last status
index before completing the DMA for the ring entry. To avoid reading
stale data, zap the old entry and check.
Signed-off-by: default avatarStephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 738a0133
......@@ -2246,20 +2246,26 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
while (hw->st_idx != hwidx) {
struct sky2_port *sky2;
struct sky2_status_le *le = hw->st_le + hw->st_idx;
unsigned port = le->css & CSS_LINK_BIT;
unsigned port;
struct net_device *dev;
struct sk_buff *skb;
u32 status;
u16 length;
u8 opcode = le->opcode;
if (!(opcode & HW_OWNER))
break;
hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
port = le->css & CSS_LINK_BIT;
dev = hw->dev[port];
sky2 = netdev_priv(dev);
length = le16_to_cpu(le->length);
status = le32_to_cpu(le->status);
switch (le->opcode & ~HW_OWNER) {
le->opcode = 0;
switch (opcode & ~HW_OWNER) {
case OP_RXSTAT:
++rx[port];
skb = sky2_receive(dev, length, status);
......@@ -2352,7 +2358,7 @@ 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", le->opcode);
"unknown status opcode 0x%x\n", opcode);
}
}
......
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