Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 145279
b: refs/heads/master
c: f11a377
h: refs/heads/master
i:
  145277: 7ff65f6
  145275: 773a4a4
  145271: c9db5b2
  145263: 1fe1be9
  145247: eec1086
  145215: 8353fa9
  145151: ae8d16e
v: v3
  • Loading branch information
David Dillow authored and David S. Miller committed May 26, 2009
1 parent 9becbcf commit c6cdc61
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 46 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c80a5cdfc5ca6533cb893154f546370da1fdb8f0
refs/heads/master: f11a377b3f4e897d11f0e8d1fc688667e2f19708
102 changes: 57 additions & 45 deletions trunk/drivers/net/r8169.c
Original file line number Diff line number Diff line change
Expand Up @@ -3554,54 +3554,64 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
int handled = 0;
int status;

/* loop handling interrupts until we have no new ones or
* we hit a invalid/hotplug case.
*/
status = RTL_R16(IntrStatus);
while (status && status != 0xffff) {
handled = 1;

/* hotplug/major error/no more work/shared irq */
if ((status == 0xffff) || !status)
goto out;

handled = 1;
/* Handle all of the error cases first. These will reset
* the chip, so just exit the loop.
*/
if (unlikely(!netif_running(dev))) {
rtl8169_asic_down(ioaddr);
break;
}

if (unlikely(!netif_running(dev))) {
rtl8169_asic_down(ioaddr);
goto out;
}
/* Work around for rx fifo overflow */
if (unlikely(status & RxFIFOOver) &&
(tp->mac_version == RTL_GIGA_MAC_VER_11)) {
netif_stop_queue(dev);
rtl8169_tx_timeout(dev);
break;
}

status &= tp->intr_mask;
RTL_W16(IntrStatus,
(status & RxFIFOOver) ? (status | RxOverflow) : status);
if (unlikely(status & SYSErr)) {
rtl8169_pcierr_interrupt(dev);
break;
}

if (!(status & tp->intr_event))
goto out;
if (status & LinkChg)
rtl8169_check_link_status(dev, tp, ioaddr);

/* Work around for rx fifo overflow */
if (unlikely(status & RxFIFOOver) &&
(tp->mac_version == RTL_GIGA_MAC_VER_11)) {
netif_stop_queue(dev);
rtl8169_tx_timeout(dev);
goto out;
}
/* We need to see the lastest version of tp->intr_mask to
* avoid ignoring an MSI interrupt and having to wait for
* another event which may never come.
*/
smp_rmb();
if (status & tp->intr_mask & tp->napi_event) {
RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
tp->intr_mask = ~tp->napi_event;

if (likely(napi_schedule_prep(&tp->napi)))
__napi_schedule(&tp->napi);
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
}
}

if (unlikely(status & SYSErr)) {
rtl8169_pcierr_interrupt(dev);
goto out;
/* We only get a new MSI interrupt when all active irq
* sources on the chip have been acknowledged. So, ack
* everything we've seen and check if new sources have become
* active to avoid blocking all interrupts from the chip.
*/
RTL_W16(IntrStatus,
(status & RxFIFOOver) ? (status | RxOverflow) : status);
status = RTL_R16(IntrStatus);
}

if (status & LinkChg)
rtl8169_check_link_status(dev, tp, ioaddr);

if (status & tp->napi_event) {
RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
tp->intr_mask = ~tp->napi_event;

if (likely(napi_schedule_prep(&tp->napi)))
__napi_schedule(&tp->napi);
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
}
}
out:
return IRQ_RETVAL(handled);
}

Expand All @@ -3617,13 +3627,15 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)

if (work_done < budget) {
napi_complete(napi);
tp->intr_mask = 0xffff;
/*
* 20040426: the barrier is not strictly required but the
* behavior of the irq handler could be less predictable
* without it. Btw, the lack of flush for the posted pci
* write is safe - FR

/* We need for force the visibility of tp->intr_mask
* for other CPUs, as we can loose an MSI interrupt
* and potentially wait for a retransmit timeout if we don't.
* The posted write to IntrMask is safe, as it will
* eventually make it to the chip and we won't loose anything
* until it does.
*/
tp->intr_mask = 0xffff;
smp_wmb();
RTL_W16(IntrMask, tp->intr_event);
}
Expand Down

0 comments on commit c6cdc61

Please sign in to comment.