aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/amd8111e.c
diff options
context:
space:
mode:
authorLiu Tao <liutao1980@gmail.com>2005-05-12 19:40:38 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-05-12 19:40:38 -0400
commitdfa1b73ffb414b64dc0452260132a090eb25bf52 (patch)
treed01ca6357ecdeb874bcf8ff3ea9a2131afd41862 /drivers/net/amd8111e.c
parent88d7bd8cb9eb8d64bf7997600b0d64f7834047c5 (diff)
[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: Liu Tao <liutao1980@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/amd8111e.c')
-rwxr-xr-xdrivers/net/amd8111e.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index f2e937abf7b4..b7dd7260cafb 100755
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -738,6 +738,7 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget)
738 short vtag; 738 short vtag;
739#endif 739#endif
740 int rx_pkt_limit = dev->quota; 740 int rx_pkt_limit = dev->quota;
741 unsigned long flags;
741 742
742 do{ 743 do{
743 /* process receive packets until we use the quota*/ 744 /* process receive packets until we use the quota*/
@@ -841,18 +842,19 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget)
841 /* Receive descriptor is empty now */ 842 /* Receive descriptor is empty now */
842 dev->quota -= num_rx_pkt; 843 dev->quota -= num_rx_pkt;
843 *budget -= num_rx_pkt; 844 *budget -= num_rx_pkt;
845
846 spin_lock_irqsave(&lp->lock, flags);
844 netif_rx_complete(dev); 847 netif_rx_complete(dev);
845 /* enable receive interrupt */
846 writel(VAL0|RINTEN0, mmio + INTEN0); 848 writel(VAL0|RINTEN0, mmio + INTEN0);
847 writel(VAL2 | RDMD0, mmio + CMD0); 849 writel(VAL2 | RDMD0, mmio + CMD0);
850 spin_unlock_irqrestore(&lp->lock, flags);
848 return 0; 851 return 0;
852
849rx_not_empty: 853rx_not_empty:
850 /* Do not call a netif_rx_complete */ 854 /* Do not call a netif_rx_complete */
851 dev->quota -= num_rx_pkt; 855 dev->quota -= num_rx_pkt;
852 *budget -= num_rx_pkt; 856 *budget -= num_rx_pkt;
853 return 1; 857 return 1;
854
855
856} 858}
857 859
858#else 860#else
@@ -1261,18 +1263,20 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
1261 struct net_device * dev = (struct net_device *) dev_id; 1263 struct net_device * dev = (struct net_device *) dev_id;
1262 struct amd8111e_priv *lp = netdev_priv(dev); 1264 struct amd8111e_priv *lp = netdev_priv(dev);
1263 void __iomem *mmio = lp->mmio; 1265 void __iomem *mmio = lp->mmio;
1264 unsigned int intr0; 1266 unsigned int intr0, intren0;
1265 unsigned int handled = 1; 1267 unsigned int handled = 1;
1266 1268
1267 if(dev == NULL) 1269 if(unlikely(dev == NULL))
1268 return IRQ_NONE; 1270 return IRQ_NONE;
1269 1271
1270 if (regs) spin_lock (&lp->lock); 1272 spin_lock(&lp->lock);
1273
1271 /* disabling interrupt */ 1274 /* disabling interrupt */
1272 writel(INTREN, mmio + CMD0); 1275 writel(INTREN, mmio + CMD0);
1273 1276
1274 /* Read interrupt status */ 1277 /* Read interrupt status */
1275 intr0 = readl(mmio + INT0); 1278 intr0 = readl(mmio + INT0);
1279 intren0 = readl(mmio + INTEN0);
1276 1280
1277 /* Process all the INT event until INTR bit is clear. */ 1281 /* Process all the INT event until INTR bit is clear. */
1278 1282
@@ -1293,11 +1297,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
1293 /* Schedule a polling routine */ 1297 /* Schedule a polling routine */
1294 __netif_rx_schedule(dev); 1298 __netif_rx_schedule(dev);
1295 } 1299 }
1296 else { 1300 else if (intren0 & RINTEN0) {
1297 printk("************Driver bug! \ 1301 printk("************Driver bug! \
1298 interrupt while in poll\n"); 1302 interrupt while in poll\n");
1299 /* Fix by disabling interrupts */ 1303 /* Fix by disable receive interrupts */
1300 writel(RINT0, mmio + INT0); 1304 writel(RINTEN0, mmio + INTEN0);
1301 } 1305 }
1302 } 1306 }
1303#else 1307#else
@@ -1321,7 +1325,7 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
1321err_no_interrupt: 1325err_no_interrupt:
1322 writel( VAL0 | INTREN,mmio + CMD0); 1326 writel( VAL0 | INTREN,mmio + CMD0);
1323 1327
1324 if (regs) spin_unlock(&lp->lock); 1328 spin_unlock(&lp->lock);
1325 1329
1326 return IRQ_RETVAL(handled); 1330 return IRQ_RETVAL(handled);
1327} 1331}