diff options
Diffstat (limited to 'drivers/net/ethernet/freescale')
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 28 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.h | 4 |
2 files changed, 22 insertions, 10 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 1e555a70b821..3f07dbd01980 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -2835,15 +2835,20 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2835 | int work_done = 0, work_done_per_q = 0; | 2835 | int work_done = 0, work_done_per_q = 0; |
2836 | int i, budget_per_q; | 2836 | int i, budget_per_q; |
2837 | int has_tx_work; | 2837 | int has_tx_work; |
2838 | unsigned long serviced_queues = 0; | 2838 | unsigned long rstat_rxf; |
2839 | int num_queues = gfargrp->num_rx_queues; | 2839 | int num_act_queues; |
2840 | 2840 | ||
2841 | budget_per_q = budget/num_queues; | ||
2842 | /* Clear IEVENT, so interrupts aren't called again | 2841 | /* Clear IEVENT, so interrupts aren't called again |
2843 | * because of the packets that have already arrived | 2842 | * because of the packets that have already arrived |
2844 | */ | 2843 | */ |
2845 | gfar_write(®s->ievent, IEVENT_RTX_MASK); | 2844 | gfar_write(®s->ievent, IEVENT_RTX_MASK); |
2846 | 2845 | ||
2846 | rstat_rxf = gfar_read(®s->rstat) & RSTAT_RXF_MASK; | ||
2847 | |||
2848 | num_act_queues = bitmap_weight(&rstat_rxf, MAX_RX_QS); | ||
2849 | if (num_act_queues) | ||
2850 | budget_per_q = budget/num_act_queues; | ||
2851 | |||
2847 | while (1) { | 2852 | while (1) { |
2848 | has_tx_work = 0; | 2853 | has_tx_work = 0; |
2849 | for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) { | 2854 | for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) { |
@@ -2856,7 +2861,8 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2856 | } | 2861 | } |
2857 | 2862 | ||
2858 | for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { | 2863 | for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { |
2859 | if (test_bit(i, &serviced_queues)) | 2864 | /* skip queue if not active */ |
2865 | if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i))) | ||
2860 | continue; | 2866 | continue; |
2861 | 2867 | ||
2862 | rx_queue = priv->rx_queue[i]; | 2868 | rx_queue = priv->rx_queue[i]; |
@@ -2866,20 +2872,24 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2866 | 2872 | ||
2867 | /* finished processing this queue */ | 2873 | /* finished processing this queue */ |
2868 | if (work_done_per_q < budget_per_q) { | 2874 | if (work_done_per_q < budget_per_q) { |
2869 | set_bit(i, &serviced_queues); | 2875 | /* clear active queue hw indication */ |
2870 | num_queues--; | 2876 | gfar_write(®s->rstat, |
2871 | if (!num_queues) | 2877 | RSTAT_CLEAR_RXF0 >> i); |
2878 | rstat_rxf &= ~(RSTAT_CLEAR_RXF0 >> i); | ||
2879 | num_act_queues--; | ||
2880 | |||
2881 | if (!num_act_queues) | ||
2872 | break; | 2882 | break; |
2873 | /* recompute budget per Rx queue */ | 2883 | /* recompute budget per Rx queue */ |
2874 | budget_per_q = | 2884 | budget_per_q = |
2875 | (budget - work_done) / num_queues; | 2885 | (budget - work_done) / num_act_queues; |
2876 | } | 2886 | } |
2877 | } | 2887 | } |
2878 | 2888 | ||
2879 | if (work_done >= budget) | 2889 | if (work_done >= budget) |
2880 | break; | 2890 | break; |
2881 | 2891 | ||
2882 | if (!num_queues && !has_tx_work) { | 2892 | if (!num_act_queues && !has_tx_work) { |
2883 | 2893 | ||
2884 | napi_complete(napi); | 2894 | napi_complete(napi); |
2885 | 2895 | ||
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 63a28d294e20..b1d0c1c77139 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h | |||
@@ -291,7 +291,9 @@ extern const char gfar_driver_version[]; | |||
291 | #define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK) | 291 | #define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK) |
292 | 292 | ||
293 | 293 | ||
294 | #define RSTAT_CLEAR_RHALT 0x00800000 | 294 | #define RSTAT_CLEAR_RHALT 0x00800000 |
295 | #define RSTAT_CLEAR_RXF0 0x00000080 | ||
296 | #define RSTAT_RXF_MASK 0x000000ff | ||
295 | 297 | ||
296 | #define TCTRL_IPCSEN 0x00004000 | 298 | #define TCTRL_IPCSEN 0x00004000 |
297 | #define TCTRL_TUCSEN 0x00002000 | 299 | #define TCTRL_TUCSEN 0x00002000 |