diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/gianfar.c')
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 87 |
1 files changed, 38 insertions, 49 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index ef95c3ae53e6..b14d7904a075 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -2920,7 +2920,7 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2920 | struct gfar_priv_rx_q *rx_queue = NULL; | 2920 | struct gfar_priv_rx_q *rx_queue = NULL; |
2921 | int work_done = 0, work_done_per_q = 0; | 2921 | int work_done = 0, work_done_per_q = 0; |
2922 | int i, budget_per_q = 0; | 2922 | int i, budget_per_q = 0; |
2923 | int has_tx_work; | 2923 | int has_tx_work = 0; |
2924 | unsigned long rstat_rxf; | 2924 | unsigned long rstat_rxf; |
2925 | int num_act_queues; | 2925 | int num_act_queues; |
2926 | 2926 | ||
@@ -2935,62 +2935,51 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2935 | if (num_act_queues) | 2935 | if (num_act_queues) |
2936 | budget_per_q = budget/num_act_queues; | 2936 | budget_per_q = budget/num_act_queues; |
2937 | 2937 | ||
2938 | while (1) { | 2938 | for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) { |
2939 | has_tx_work = 0; | 2939 | tx_queue = priv->tx_queue[i]; |
2940 | for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) { | 2940 | /* run Tx cleanup to completion */ |
2941 | tx_queue = priv->tx_queue[i]; | 2941 | if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) { |
2942 | /* run Tx cleanup to completion */ | 2942 | gfar_clean_tx_ring(tx_queue); |
2943 | if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) { | 2943 | has_tx_work = 1; |
2944 | gfar_clean_tx_ring(tx_queue); | ||
2945 | has_tx_work = 1; | ||
2946 | } | ||
2947 | } | 2944 | } |
2945 | } | ||
2948 | 2946 | ||
2949 | for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { | 2947 | for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { |
2950 | /* skip queue if not active */ | 2948 | /* skip queue if not active */ |
2951 | if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i))) | 2949 | if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i))) |
2952 | continue; | 2950 | continue; |
2953 | |||
2954 | rx_queue = priv->rx_queue[i]; | ||
2955 | work_done_per_q = | ||
2956 | gfar_clean_rx_ring(rx_queue, budget_per_q); | ||
2957 | work_done += work_done_per_q; | ||
2958 | |||
2959 | /* finished processing this queue */ | ||
2960 | if (work_done_per_q < budget_per_q) { | ||
2961 | /* clear active queue hw indication */ | ||
2962 | gfar_write(®s->rstat, | ||
2963 | RSTAT_CLEAR_RXF0 >> i); | ||
2964 | rstat_rxf &= ~(RSTAT_CLEAR_RXF0 >> i); | ||
2965 | num_act_queues--; | ||
2966 | |||
2967 | if (!num_act_queues) | ||
2968 | break; | ||
2969 | /* recompute budget per Rx queue */ | ||
2970 | budget_per_q = | ||
2971 | (budget - work_done) / num_act_queues; | ||
2972 | } | ||
2973 | } | ||
2974 | 2951 | ||
2975 | if (work_done >= budget) | 2952 | rx_queue = priv->rx_queue[i]; |
2976 | break; | 2953 | work_done_per_q = |
2954 | gfar_clean_rx_ring(rx_queue, budget_per_q); | ||
2955 | work_done += work_done_per_q; | ||
2956 | |||
2957 | /* finished processing this queue */ | ||
2958 | if (work_done_per_q < budget_per_q) { | ||
2959 | /* clear active queue hw indication */ | ||
2960 | gfar_write(®s->rstat, | ||
2961 | RSTAT_CLEAR_RXF0 >> i); | ||
2962 | num_act_queues--; | ||
2963 | |||
2964 | if (!num_act_queues) | ||
2965 | break; | ||
2966 | } | ||
2967 | } | ||
2977 | 2968 | ||
2978 | if (!num_act_queues && !has_tx_work) { | 2969 | if (!num_act_queues && !has_tx_work) { |
2979 | 2970 | ||
2980 | napi_complete(napi); | 2971 | napi_complete(napi); |
2981 | 2972 | ||
2982 | /* Clear the halt bit in RSTAT */ | 2973 | /* Clear the halt bit in RSTAT */ |
2983 | gfar_write(®s->rstat, gfargrp->rstat); | 2974 | gfar_write(®s->rstat, gfargrp->rstat); |
2984 | 2975 | ||
2985 | gfar_write(®s->imask, IMASK_DEFAULT); | 2976 | gfar_write(®s->imask, IMASK_DEFAULT); |
2986 | 2977 | ||
2987 | /* If we are coalescing interrupts, update the timer | 2978 | /* If we are coalescing interrupts, update the timer |
2988 | * Otherwise, clear it | 2979 | * Otherwise, clear it |
2989 | */ | 2980 | */ |
2990 | gfar_configure_coalescing(priv, gfargrp->rx_bit_map, | 2981 | gfar_configure_coalescing(priv, gfargrp->rx_bit_map, |
2991 | gfargrp->tx_bit_map); | 2982 | gfargrp->tx_bit_map); |
2992 | break; | ||
2993 | } | ||
2994 | } | 2983 | } |
2995 | 2984 | ||
2996 | return work_done; | 2985 | return work_done; |