Commit dfa1b73f authored by Liu Tao's avatar Liu Tao Committed by Jeff Garzik

[PATCH] drivers/net/amd8111e.c: fix NAPI interrupt in poll

  
  This patch makes the netif_rx_complete() and rx_interrupt_enable
  atomic when exiting the poll() method, so to avoid interrupt in poll.
  It also fixes the rx interrupt check logic in interrupt handler.
Signed-off-by: default avatarLiu Tao <liutao1980@gmail.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 88d7bd8c
...@@ -738,6 +738,7 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget) ...@@ -738,6 +738,7 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget)
short vtag; short vtag;
#endif #endif
int rx_pkt_limit = dev->quota; int rx_pkt_limit = dev->quota;
unsigned long flags;
do{ do{
/* process receive packets until we use the quota*/ /* process receive packets until we use the quota*/
...@@ -841,18 +842,19 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget) ...@@ -841,18 +842,19 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget)
/* Receive descriptor is empty now */ /* Receive descriptor is empty now */
dev->quota -= num_rx_pkt; dev->quota -= num_rx_pkt;
*budget -= num_rx_pkt; *budget -= num_rx_pkt;
spin_lock_irqsave(&lp->lock, flags);
netif_rx_complete(dev); netif_rx_complete(dev);
/* enable receive interrupt */
writel(VAL0|RINTEN0, mmio + INTEN0); writel(VAL0|RINTEN0, mmio + INTEN0);
writel(VAL2 | RDMD0, mmio + CMD0); writel(VAL2 | RDMD0, mmio + CMD0);
spin_unlock_irqrestore(&lp->lock, flags);
return 0; return 0;
rx_not_empty: rx_not_empty:
/* Do not call a netif_rx_complete */ /* Do not call a netif_rx_complete */
dev->quota -= num_rx_pkt; dev->quota -= num_rx_pkt;
*budget -= num_rx_pkt; *budget -= num_rx_pkt;
return 1; return 1;
} }
#else #else
...@@ -1261,18 +1263,20 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg ...@@ -1261,18 +1263,20 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
struct net_device * dev = (struct net_device *) dev_id; struct net_device * dev = (struct net_device *) dev_id;
struct amd8111e_priv *lp = netdev_priv(dev); struct amd8111e_priv *lp = netdev_priv(dev);
void __iomem *mmio = lp->mmio; void __iomem *mmio = lp->mmio;
unsigned int intr0; unsigned int intr0, intren0;
unsigned int handled = 1; unsigned int handled = 1;
if(dev == NULL) if(unlikely(dev == NULL))
return IRQ_NONE; return IRQ_NONE;
if (regs) spin_lock (&lp->lock); spin_lock(&lp->lock);
/* disabling interrupt */ /* disabling interrupt */
writel(INTREN, mmio + CMD0); writel(INTREN, mmio + CMD0);
/* Read interrupt status */ /* Read interrupt status */
intr0 = readl(mmio + INT0); intr0 = readl(mmio + INT0);
intren0 = readl(mmio + INTEN0);
/* Process all the INT event until INTR bit is clear. */ /* Process all the INT event until INTR bit is clear. */
...@@ -1293,11 +1297,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg ...@@ -1293,11 +1297,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
/* Schedule a polling routine */ /* Schedule a polling routine */
__netif_rx_schedule(dev); __netif_rx_schedule(dev);
} }
else { else if (intren0 & RINTEN0) {
printk("************Driver bug! \ printk("************Driver bug! \
interrupt while in poll\n"); interrupt while in poll\n");
/* Fix by disabling interrupts */ /* Fix by disable receive interrupts */
writel(RINT0, mmio + INT0); writel(RINTEN0, mmio + INTEN0);
} }
} }
#else #else
...@@ -1321,7 +1325,7 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg ...@@ -1321,7 +1325,7 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
err_no_interrupt: err_no_interrupt:
writel( VAL0 | INTREN,mmio + CMD0); writel( VAL0 | INTREN,mmio + CMD0);
if (regs) spin_unlock(&lp->lock); spin_unlock(&lp->lock);
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
......
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