summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/fec_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 299b1f494065..cff4a73e9574 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -893,7 +893,7 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
hwtstamps->hwtstamp = ns_to_ktime(ns);
}
-static void noinline
+static int noinline
fec_enet_tx(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1003,6 +1003,8 @@ extern int __trace2; __trace2 = 1;
netif_wake_queue(ndev);
fep->start_ns = sched_clock();
}
+
+ return pkts_compl;
}
static void
@@ -1198,8 +1200,6 @@ fec_enet_rx(struct net_device *ndev, int budget)
if ((status & BD_ENET_RX_LAST) == 0)
netdev_err(ndev, "rcv is not +last\n");
- writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
-
/* Check for errors. */
if (status & BD_ENET_RX_ERROR) {
ndev->stats.rx_errors++;
@@ -1316,23 +1316,30 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
{
struct net_device *ndev = napi->dev;
struct fec_enet_private *fep = netdev_priv(ndev);
- int pkts;
+ int rx_work, rx_pkts, tx_work, tx_pkts;
- /*
- * Clear any pending transmit or receive interrupts before
- * processing the rings to avoid racing with the hardware.
- */
- writel(FEC_ENET_RXF | FEC_ENET_TXF, fep->hwp + FEC_IEVENT);
+ for (rx_work = tx_work = 0; rx_work < budget; ) {
+ /*
+ * Clear any pending transmit or receive interrupts before
+ * processing the rings to avoid racing with the hardware.
+ */
+ writel(FEC_ENET_RXF | FEC_ENET_TXF, fep->hwp + FEC_IEVENT);
- pkts = fec_enet_rx(ndev, budget);
+ rx_pkts = fec_enet_rx(ndev, budget - total_work);
+ tx_pkts = fec_enet_tx(ndev);
- fec_enet_tx(ndev);
+ if (!rx_pkts && !tx_pkts)
+ break;
+
+ rx_work += rx_pkts;
+ tx_work += tx_pkts;
+ }
- if (pkts < budget) {
+ if (rx_work < budget) {
napi_complete(napi);
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
}
- return pkts;
+ return rx_work;
}
/* ------------------------------------------------------------------------- */