| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- --- a/drivers/net/ethernet/freescale/gianfar.c
- +++ b/drivers/net/ethernet/freescale/gianfar.c
- @@ -2835,7 +2835,7 @@ static int gfar_poll(struct napi_struct
- struct gfar_priv_rx_q *rx_queue = NULL;
- int work_done = 0, work_done_per_q = 0;
- int i, budget_per_q = 0;
- - int has_tx_work;
- + int has_tx_work = 0;
- unsigned long rstat_rxf;
- int num_act_queues;
-
- @@ -2850,62 +2850,48 @@ static int gfar_poll(struct napi_struct
- if (num_act_queues)
- budget_per_q = budget/num_act_queues;
-
- - while (1) {
- - has_tx_work = 0;
- - for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
- - tx_queue = priv->tx_queue[i];
- - /* run Tx cleanup to completion */
- - if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
- - gfar_clean_tx_ring(tx_queue);
- - has_tx_work = 1;
- - }
- - }
- -
- - for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
- - /* skip queue if not active */
- - if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i)))
- - continue;
- -
- - rx_queue = priv->rx_queue[i];
- - work_done_per_q =
- - gfar_clean_rx_ring(rx_queue, budget_per_q);
- - work_done += work_done_per_q;
- -
- - /* finished processing this queue */
- - if (work_done_per_q < budget_per_q) {
- - /* clear active queue hw indication */
- - gfar_write(®s->rstat,
- - RSTAT_CLEAR_RXF0 >> i);
- - rstat_rxf &= ~(RSTAT_CLEAR_RXF0 >> i);
- - num_act_queues--;
- -
- - if (!num_act_queues)
- - break;
- - /* recompute budget per Rx queue */
- - budget_per_q =
- - (budget - work_done) / num_act_queues;
- - }
- + for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
- + tx_queue = priv->tx_queue[i];
- + /* run Tx cleanup to completion */
- + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
- + gfar_clean_tx_ring(tx_queue);
- + has_tx_work = 1;
- }
- + }
-
- - if (work_done >= budget)
- - break;
- + for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
- + /* skip queue if not active */
- + if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i)))
- + continue;
- +
- + rx_queue = priv->rx_queue[i];
- + work_done_per_q = gfar_clean_rx_ring(rx_queue, budget_per_q);
- + work_done += work_done_per_q;
- +
- + /* finished processing this queue */
- + if (work_done_per_q < budget_per_q) {
- + /* clear active queue hw indication */
- + gfar_write(®s->rstat, RSTAT_CLEAR_RXF0 >> i);
- + num_act_queues--;
-
- - if (!num_act_queues && !has_tx_work) {
- + if (!num_act_queues)
- + break;
- + }
- + }
-
- - napi_complete(napi);
- + if (!num_act_queues && !has_tx_work) {
- + napi_complete(napi);
-
- - /* Clear the halt bit in RSTAT */
- - gfar_write(®s->rstat, gfargrp->rstat);
- + /* Clear the halt bit in RSTAT */
- + gfar_write(®s->rstat, gfargrp->rstat);
-
- - gfar_write(®s->imask, IMASK_DEFAULT);
- + gfar_write(®s->imask, IMASK_DEFAULT);
-
- - /* If we are coalescing interrupts, update the timer
- - * Otherwise, clear it
- - */
- - gfar_configure_coalescing(priv, gfargrp->rx_bit_map,
- - gfargrp->tx_bit_map);
- - break;
- - }
- + /* If we are coalescing interrupts, update the timer
- + * Otherwise, clear it
- + */
- + gfar_configure_coalescing(priv, gfargrp->rx_bit_map,
- + gfargrp->tx_bit_map);
- }
-
- return work_done;
|