aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tulip/interrupt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tulip/interrupt.c')
-rw-r--r--drivers/net/tulip/interrupt.c54
1 files changed, 23 insertions, 31 deletions
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 53efd6694e75..365331446387 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -103,28 +103,29 @@ int tulip_refill_rx(struct net_device *dev)
103void oom_timer(unsigned long data) 103void oom_timer(unsigned long data)
104{ 104{
105 struct net_device *dev = (struct net_device *)data; 105 struct net_device *dev = (struct net_device *)data;
106 netif_rx_schedule(dev); 106 struct tulip_private *tp = netdev_priv(dev);
107 netif_rx_schedule(dev, &tp->napi);
107} 108}
108 109
109int tulip_poll(struct net_device *dev, int *budget) 110int tulip_poll(struct napi_struct *napi, int budget)
110{ 111{
111 struct tulip_private *tp = netdev_priv(dev); 112 struct tulip_private *tp = container_of(napi, struct tulip_private, napi);
113 struct net_device *dev = tp->dev;
112 int entry = tp->cur_rx % RX_RING_SIZE; 114 int entry = tp->cur_rx % RX_RING_SIZE;
113 int rx_work_limit = *budget; 115 int work_done = 0;
116#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
114 int received = 0; 117 int received = 0;
118#endif
115 119
116 if (!netif_running(dev)) 120 if (!netif_running(dev))
117 goto done; 121 goto done;
118 122
119 if (rx_work_limit > dev->quota)
120 rx_work_limit = dev->quota;
121
122#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION 123#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
123 124
124/* that one buffer is needed for mit activation; or might be a 125/* that one buffer is needed for mit activation; or might be a
125 bug in the ring buffer code; check later -- JHS*/ 126 bug in the ring buffer code; check later -- JHS*/
126 127
127 if (rx_work_limit >=RX_RING_SIZE) rx_work_limit--; 128 if (budget >=RX_RING_SIZE) budget--;
128#endif 129#endif
129 130
130 if (tulip_debug > 4) 131 if (tulip_debug > 4)
@@ -144,14 +145,13 @@ int tulip_poll(struct net_device *dev, int *budget)
144 while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) { 145 while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
145 s32 status = le32_to_cpu(tp->rx_ring[entry].status); 146 s32 status = le32_to_cpu(tp->rx_ring[entry].status);
146 147
147
148 if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx) 148 if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
149 break; 149 break;
150 150
151 if (tulip_debug > 5) 151 if (tulip_debug > 5)
152 printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n", 152 printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
153 dev->name, entry, status); 153 dev->name, entry, status);
154 if (--rx_work_limit < 0) 154 if (work_done++ >= budget)
155 goto not_done; 155 goto not_done;
156 156
157 if ((status & 0x38008300) != 0x0300) { 157 if ((status & 0x38008300) != 0x0300) {
@@ -238,7 +238,9 @@ int tulip_poll(struct net_device *dev, int *budget)
238 tp->stats.rx_packets++; 238 tp->stats.rx_packets++;
239 tp->stats.rx_bytes += pkt_len; 239 tp->stats.rx_bytes += pkt_len;
240 } 240 }
241 received++; 241#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
242 received++;
243#endif
242 244
243 entry = (++tp->cur_rx) % RX_RING_SIZE; 245 entry = (++tp->cur_rx) % RX_RING_SIZE;
244 if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/4) 246 if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/4)
@@ -296,17 +298,15 @@ done:
296 298
297#endif /* CONFIG_TULIP_NAPI_HW_MITIGATION */ 299#endif /* CONFIG_TULIP_NAPI_HW_MITIGATION */
298 300
299 dev->quota -= received;
300 *budget -= received;
301
302 tulip_refill_rx(dev); 301 tulip_refill_rx(dev);
303 302
304 /* If RX ring is not full we are out of memory. */ 303 /* If RX ring is not full we are out of memory. */
305 if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) goto oom; 304 if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
305 goto oom;
306 306
307 /* Remove us from polling list and enable RX intr. */ 307 /* Remove us from polling list and enable RX intr. */
308 308
309 netif_rx_complete(dev); 309 netif_rx_complete(dev, napi);
310 iowrite32(tulip_tbl[tp->chip_id].valid_intrs, tp->base_addr+CSR7); 310 iowrite32(tulip_tbl[tp->chip_id].valid_intrs, tp->base_addr+CSR7);
311 311
312 /* The last op happens after poll completion. Which means the following: 312 /* The last op happens after poll completion. Which means the following:
@@ -320,28 +320,20 @@ done:
320 * processed irqs. But it must not result in losing events. 320 * processed irqs. But it must not result in losing events.
321 */ 321 */
322 322
323 return 0; 323 return work_done;
324 324
325 not_done: 325 not_done:
326 if (!received) {
327
328 received = dev->quota; /* Not to happen */
329 }
330 dev->quota -= received;
331 *budget -= received;
332
333 if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 || 326 if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
334 tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) 327 tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
335 tulip_refill_rx(dev); 328 tulip_refill_rx(dev);
336 329
337 if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) goto oom; 330 if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
338 331 goto oom;
339 return 1;
340 332
333 return work_done;
341 334
342 oom: /* Executed with RX ints disabled */ 335 oom: /* Executed with RX ints disabled */
343 336
344
345 /* Start timer, stop polling, but do not enable rx interrupts. */ 337 /* Start timer, stop polling, but do not enable rx interrupts. */
346 mod_timer(&tp->oom_timer, jiffies+1); 338 mod_timer(&tp->oom_timer, jiffies+1);
347 339
@@ -350,9 +342,9 @@ done:
350 * before we did netif_rx_complete(). See? We would lose it. */ 342 * before we did netif_rx_complete(). See? We would lose it. */
351 343
352 /* remove ourselves from the polling list */ 344 /* remove ourselves from the polling list */
353 netif_rx_complete(dev); 345 netif_rx_complete(dev, napi);
354 346
355 return 0; 347 return work_done;
356} 348}
357 349
358#else /* CONFIG_TULIP_NAPI */ 350#else /* CONFIG_TULIP_NAPI */
@@ -534,7 +526,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
534 rxd++; 526 rxd++;
535 /* Mask RX intrs and add the device to poll list. */ 527 /* Mask RX intrs and add the device to poll list. */
536 iowrite32(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7); 528 iowrite32(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
537 netif_rx_schedule(dev); 529 netif_rx_schedule(dev, &tp->napi);
538 530
539 if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass))) 531 if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
540 break; 532 break;