Commit cd024c8b authored by David S. Miller's avatar David S. Miller

[TG3]: Fix missing memory barriers and SD_STATUS_UPDATED bit clearing.

There must be a rmb() between reading the status block tag
and calling tg3_has_work().  This was missing in tg3_mis()
and tg3_interrupt_tagged().  tg3_poll() got it right.

Also, SD_STATUS_UPDATED must be cleared in the status block
right before we call tg3_has_work().  Only tg3_poll() got this
wrong.

Based upon patches and commentary from Grant Grundler and
Michael Chan.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c54d7e03
...@@ -2929,6 +2929,7 @@ static int tg3_poll(struct net_device *netdev, int *budget) ...@@ -2929,6 +2929,7 @@ static int tg3_poll(struct net_device *netdev, int *budget)
if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
tp->last_tag = sblk->status_tag; tp->last_tag = sblk->status_tag;
rmb(); rmb();
sblk->status &= ~SD_STATUS_UPDATED;
/* if no more work, tell net stack and NIC we're done */ /* if no more work, tell net stack and NIC we're done */
done = !tg3_has_work(tp); done = !tg3_has_work(tp);
...@@ -2964,6 +2965,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2964,6 +2965,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
*/ */
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
tp->last_tag = sblk->status_tag; tp->last_tag = sblk->status_tag;
rmb();
sblk->status &= ~SD_STATUS_UPDATED; sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp))) if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */ netif_rx_schedule(dev); /* schedule NAPI poll */
...@@ -3051,6 +3053,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r ...@@ -3051,6 +3053,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
0x00000001); 0x00000001);
tp->last_tag = sblk->status_tag; tp->last_tag = sblk->status_tag;
rmb();
sblk->status &= ~SD_STATUS_UPDATED; sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp))) if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */ netif_rx_schedule(dev); /* schedule NAPI poll */
......
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