diff options
-rw-r--r-- | drivers/net/ibm_newemac/mal.c | 55 | ||||
-rw-r--r-- | drivers/net/ibm_newemac/mal.h | 2 |
2 files changed, 20 insertions, 37 deletions
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index c4335b7d308c..58854117b1a9 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c | |||
@@ -235,10 +235,10 @@ static irqreturn_t mal_serr(int irq, void *dev_instance) | |||
235 | 235 | ||
236 | static inline void mal_schedule_poll(struct mal_instance *mal) | 236 | static inline void mal_schedule_poll(struct mal_instance *mal) |
237 | { | 237 | { |
238 | if (likely(netif_rx_schedule_prep(&mal->poll_dev))) { | 238 | if (likely(napi_schedule_prep(&mal->napi))) { |
239 | MAL_DBG2(mal, "schedule_poll" NL); | 239 | MAL_DBG2(mal, "schedule_poll" NL); |
240 | mal_disable_eob_irq(mal); | 240 | mal_disable_eob_irq(mal); |
241 | __netif_rx_schedule(&mal->poll_dev); | 241 | __napi_schedule(&mal->napi); |
242 | } else | 242 | } else |
243 | MAL_DBG2(mal, "already in poll" NL); | 243 | MAL_DBG2(mal, "already in poll" NL); |
244 | } | 244 | } |
@@ -318,8 +318,7 @@ void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac) | |||
318 | msleep(1); | 318 | msleep(1); |
319 | 319 | ||
320 | /* Synchronize with the MAL NAPI poller. */ | 320 | /* Synchronize with the MAL NAPI poller. */ |
321 | while (test_bit(__LINK_STATE_RX_SCHED, &mal->poll_dev.state)) | 321 | napi_disable(&mal->napi); |
322 | msleep(1); | ||
323 | } | 322 | } |
324 | 323 | ||
325 | void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac) | 324 | void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac) |
@@ -330,11 +329,11 @@ void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac) | |||
330 | // XXX might want to kick a poll now... | 329 | // XXX might want to kick a poll now... |
331 | } | 330 | } |
332 | 331 | ||
333 | static int mal_poll(struct net_device *ndev, int *budget) | 332 | static int mal_poll(struct napi_struct *napi, int budget) |
334 | { | 333 | { |
335 | struct mal_instance *mal = netdev_priv(ndev); | 334 | struct mal_instance *mal = container_of(napi, struct mal_instance, napi); |
336 | struct list_head *l; | 335 | struct list_head *l; |
337 | int rx_work_limit = min(ndev->quota, *budget), received = 0, done; | 336 | int received = 0; |
338 | unsigned long flags; | 337 | unsigned long flags; |
339 | 338 | ||
340 | MAL_DBG2(mal, "poll(%d) %d ->" NL, *budget, | 339 | MAL_DBG2(mal, "poll(%d) %d ->" NL, *budget, |
@@ -358,26 +357,21 @@ static int mal_poll(struct net_device *ndev, int *budget) | |||
358 | int n; | 357 | int n; |
359 | if (unlikely(test_bit(MAL_COMMAC_POLL_DISABLED, &mc->flags))) | 358 | if (unlikely(test_bit(MAL_COMMAC_POLL_DISABLED, &mc->flags))) |
360 | continue; | 359 | continue; |
361 | n = mc->ops->poll_rx(mc->dev, rx_work_limit); | 360 | n = mc->ops->poll_rx(mc->dev, budget); |
362 | if (n) { | 361 | if (n) { |
363 | received += n; | 362 | received += n; |
364 | rx_work_limit -= n; | 363 | budget -= n; |
365 | if (rx_work_limit <= 0) { | 364 | if (budget <= 0) |
366 | done = 0; | 365 | goto more_work; // XXX What if this is the last one ? |
367 | // XXX What if this is the last one ? | ||
368 | goto more_work; | ||
369 | } | ||
370 | } | 366 | } |
371 | } | 367 | } |
372 | 368 | ||
373 | /* We need to disable IRQs to protect from RXDE IRQ here */ | 369 | /* We need to disable IRQs to protect from RXDE IRQ here */ |
374 | spin_lock_irqsave(&mal->lock, flags); | 370 | spin_lock_irqsave(&mal->lock, flags); |
375 | __netif_rx_complete(ndev); | 371 | __napi_complete(napi); |
376 | mal_enable_eob_irq(mal); | 372 | mal_enable_eob_irq(mal); |
377 | spin_unlock_irqrestore(&mal->lock, flags); | 373 | spin_unlock_irqrestore(&mal->lock, flags); |
378 | 374 | ||
379 | done = 1; | ||
380 | |||
381 | /* Check for "rotting" packet(s) */ | 375 | /* Check for "rotting" packet(s) */ |
382 | list_for_each(l, &mal->poll_list) { | 376 | list_for_each(l, &mal->poll_list) { |
383 | struct mal_commac *mc = | 377 | struct mal_commac *mc = |
@@ -387,12 +381,12 @@ static int mal_poll(struct net_device *ndev, int *budget) | |||
387 | if (unlikely(mc->ops->peek_rx(mc->dev) || | 381 | if (unlikely(mc->ops->peek_rx(mc->dev) || |
388 | test_bit(MAL_COMMAC_RX_STOPPED, &mc->flags))) { | 382 | test_bit(MAL_COMMAC_RX_STOPPED, &mc->flags))) { |
389 | MAL_DBG2(mal, "rotting packet" NL); | 383 | MAL_DBG2(mal, "rotting packet" NL); |
390 | if (netif_rx_reschedule(ndev, received)) | 384 | if (napi_reschedule(napi)) |
391 | mal_disable_eob_irq(mal); | 385 | mal_disable_eob_irq(mal); |
392 | else | 386 | else |
393 | MAL_DBG2(mal, "already in poll list" NL); | 387 | MAL_DBG2(mal, "already in poll list" NL); |
394 | 388 | ||
395 | if (rx_work_limit > 0) | 389 | if (budget > 0) |
396 | goto again; | 390 | goto again; |
397 | else | 391 | else |
398 | goto more_work; | 392 | goto more_work; |
@@ -401,13 +395,8 @@ static int mal_poll(struct net_device *ndev, int *budget) | |||
401 | } | 395 | } |
402 | 396 | ||
403 | more_work: | 397 | more_work: |
404 | ndev->quota -= received; | 398 | MAL_DBG2(mal, "poll() %d <- %d" NL, budget, received); |
405 | *budget -= received; | 399 | return received; |
406 | |||
407 | MAL_DBG2(mal, "poll() %d <- %d" NL, *budget, | ||
408 | done ? 0 : 1); | ||
409 | |||
410 | return done ? 0 : 1; | ||
411 | } | 400 | } |
412 | 401 | ||
413 | static void mal_reset(struct mal_instance *mal) | 402 | static void mal_reset(struct mal_instance *mal) |
@@ -538,11 +527,8 @@ static int __devinit mal_probe(struct of_device *ofdev, | |||
538 | } | 527 | } |
539 | 528 | ||
540 | INIT_LIST_HEAD(&mal->poll_list); | 529 | INIT_LIST_HEAD(&mal->poll_list); |
541 | set_bit(__LINK_STATE_START, &mal->poll_dev.state); | 530 | mal->napi.weight = CONFIG_IBM_NEW_EMAC_POLL_WEIGHT; |
542 | mal->poll_dev.weight = CONFIG_IBM_NEW_EMAC_POLL_WEIGHT; | 531 | mal->napi.poll = mal_poll; |
543 | mal->poll_dev.poll = mal_poll; | ||
544 | mal->poll_dev.priv = mal; | ||
545 | atomic_set(&mal->poll_dev.refcnt, 1); | ||
546 | INIT_LIST_HEAD(&mal->list); | 532 | INIT_LIST_HEAD(&mal->list); |
547 | spin_lock_init(&mal->lock); | 533 | spin_lock_init(&mal->lock); |
548 | 534 | ||
@@ -653,11 +639,8 @@ static int __devexit mal_remove(struct of_device *ofdev) | |||
653 | 639 | ||
654 | MAL_DBG(mal, "remove" NL); | 640 | MAL_DBG(mal, "remove" NL); |
655 | 641 | ||
656 | /* Syncronize with scheduled polling, | 642 | /* Synchronize with scheduled polling */ |
657 | stolen from net/core/dev.c:dev_close() | 643 | napi_disable(&mal->napi); |
658 | */ | ||
659 | clear_bit(__LINK_STATE_START, &mal->poll_dev.state); | ||
660 | netif_poll_disable(&mal->poll_dev); | ||
661 | 644 | ||
662 | if (!list_empty(&mal->list)) { | 645 | if (!list_empty(&mal->list)) { |
663 | /* This is *very* bad */ | 646 | /* This is *very* bad */ |
diff --git a/drivers/net/ibm_newemac/mal.h b/drivers/net/ibm_newemac/mal.h index 57b69dc32e9d..cb1a16d589fe 100644 --- a/drivers/net/ibm_newemac/mal.h +++ b/drivers/net/ibm_newemac/mal.h | |||
@@ -197,7 +197,7 @@ struct mal_instance { | |||
197 | int serr_irq; /* MAL System Error IRQ */ | 197 | int serr_irq; /* MAL System Error IRQ */ |
198 | 198 | ||
199 | struct list_head poll_list; | 199 | struct list_head poll_list; |
200 | struct net_device poll_dev; | 200 | struct napi_struct napi; |
201 | 201 | ||
202 | struct list_head list; | 202 | struct list_head list; |
203 | u32 tx_chan_mask; | 203 | u32 tx_chan_mask; |