diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e795c33b982d..30b1cca8144c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -3576,7 +3576,7 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget) | |||
3576 | if (sblk->idx[0].tx_consumer != tp->tx_cons) { | 3576 | if (sblk->idx[0].tx_consumer != tp->tx_cons) { |
3577 | tg3_tx(tp); | 3577 | tg3_tx(tp); |
3578 | if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING)) | 3578 | if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING)) |
3579 | return 0; | 3579 | return work_done; |
3580 | } | 3580 | } |
3581 | 3581 | ||
3582 | /* run RX thread, within the bounds set by NAPI. | 3582 | /* run RX thread, within the bounds set by NAPI. |
@@ -3593,6 +3593,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) | |||
3593 | { | 3593 | { |
3594 | struct tg3 *tp = container_of(napi, struct tg3, napi); | 3594 | struct tg3 *tp = container_of(napi, struct tg3, napi); |
3595 | int work_done = 0; | 3595 | int work_done = 0; |
3596 | struct tg3_hw_status *sblk = tp->hw_status; | ||
3596 | 3597 | ||
3597 | while (1) { | 3598 | while (1) { |
3598 | work_done = tg3_poll_work(tp, work_done, budget); | 3599 | work_done = tg3_poll_work(tp, work_done, budget); |
@@ -3603,15 +3604,17 @@ static int tg3_poll(struct napi_struct *napi, int budget) | |||
3603 | if (unlikely(work_done >= budget)) | 3604 | if (unlikely(work_done >= budget)) |
3604 | break; | 3605 | break; |
3605 | 3606 | ||
3606 | if (likely(!tg3_has_work(tp))) { | 3607 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) { |
3607 | struct tg3_hw_status *sblk = tp->hw_status; | 3608 | /* tp->last_tag is used in tg3_restart_ints() below |
3608 | 3609 | * to tell the hw how much work has been processed, | |
3609 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) { | 3610 | * so we must read it before checking for more work. |
3610 | tp->last_tag = sblk->status_tag; | 3611 | */ |
3611 | rmb(); | 3612 | tp->last_tag = sblk->status_tag; |
3612 | } else | 3613 | rmb(); |
3613 | sblk->status &= ~SD_STATUS_UPDATED; | 3614 | } else |
3615 | sblk->status &= ~SD_STATUS_UPDATED; | ||
3614 | 3616 | ||
3617 | if (likely(!tg3_has_work(tp))) { | ||
3615 | netif_rx_complete(tp->dev, napi); | 3618 | netif_rx_complete(tp->dev, napi); |
3616 | tg3_restart_ints(tp); | 3619 | tg3_restart_ints(tp); |
3617 | break; | 3620 | break; |
@@ -3621,9 +3624,10 @@ static int tg3_poll(struct napi_struct *napi, int budget) | |||
3621 | return work_done; | 3624 | return work_done; |
3622 | 3625 | ||
3623 | tx_recovery: | 3626 | tx_recovery: |
3627 | /* work_done is guaranteed to be less than budget. */ | ||
3624 | netif_rx_complete(tp->dev, napi); | 3628 | netif_rx_complete(tp->dev, napi); |
3625 | schedule_work(&tp->reset_task); | 3629 | schedule_work(&tp->reset_task); |
3626 | return 0; | 3630 | return work_done; |
3627 | } | 3631 | } |
3628 | 3632 | ||
3629 | static void tg3_irq_quiesce(struct tg3 *tp) | 3633 | static void tg3_irq_quiesce(struct tg3 *tp) |