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.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 578f0bdac309..299b1f494065 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -254,6 +254,10 @@ static unsigned copybreak = 200;
module_param(copybreak, uint, 0644);
MODULE_PARM_DESC(copybreak,
"Maximum size of packet that is copied to a new buffer on receive");
+static unsigned long total_stopped;
+module_param(total_stopped, ulong, 0644);
+static unsigned long start_latency;
+module_param(start_latency, ulong, 0644);
static bool fec_enet_rx_zerocopy(struct fec_enet_private *fep, unsigned pktlen)
{
@@ -457,6 +461,15 @@ static bool fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev
unsigned short status;
unsigned int index, buflen, estatus;
+ if (fep->start_ns) {
+ unsigned delta = sched_clock() - fep->start_ns;
+ if (start_latency == 0 && delta < 1000000)
+ WARN_ON(1);
+ if (delta < 1000000)
+ start_latency += delta;
+ fep->start_ns = 0;
+ }
+
/* Protocol checksum off-load for TCP and UDP. */
if (fec_enet_clear_csum(skb, ndev))
return false;
@@ -576,8 +589,10 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_OK;
}
- if (ring_free(fep->tx_next, fep->tx_dirty, fep->tx_ring_size) < fep->tx_min)
+ if (ring_free(fep->tx_next, fep->tx_dirty, fep->tx_ring_size) < fep->tx_min) {
+ fep->stop_ns = sched_clock();
netif_stop_queue(ndev);
+ }
return NETDEV_TX_OK;
}
@@ -979,8 +994,15 @@ fec_enet_tx(struct net_device *ndev)
if (netif_queue_stopped(ndev) &&
ring_free(fep->tx_next, fep->tx_dirty, fep->tx_ring_size) >=
- fep->tx_min)
+ fep->tx_min) {
+ total_stopped += sched_clock() - fep->stop_ns;
+ if (start_latency == 0) {
+// WARN_ON(1);
+extern int __trace2; __trace2 = 1;
+ }
netif_wake_queue(ndev);
+ fep->start_ns = sched_clock();
+ }
}
static void
@@ -1006,7 +1028,7 @@ fec_enet_receive(struct sk_buff *skb, union bufdesc_u *bdp, struct net_device *n
napi_gro_receive(&fep->napi, skb);
}
-static void
+static void noinline
fec_enet_receive_copy(unsigned pkt_len, unsigned index, union bufdesc_u *bdp, struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1076,7 +1098,7 @@ fec_enet_receive_copy(unsigned pkt_len, unsigned index, union bufdesc_u *bdp, st
fec_enet_receive(skb, bdp, ndev);
}
-static void
+static void noinline
fec_enet_receive_nocopy(unsigned pkt_len, unsigned index, union bufdesc_u *bdp,
struct net_device *ndev)
{
@@ -1143,11 +1165,10 @@ fec_enet_receive_nocopy(unsigned pkt_len, unsigned index, union bufdesc_u *bdp,
* not been given to the system, we just set the empty indicator,
* effectively tossing the packet.
*/
-static int
+static int noinline
fec_enet_rx(struct net_device *ndev, int budget)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- ushort pkt_len;
int pkt_received = 0;
unsigned int index = fep->rx_next;
@@ -1160,7 +1181,7 @@ fec_enet_rx(struct net_device *ndev, int budget)
*/
do {
union bufdesc_u *bdp = fec_enet_rx_get(index, fep);
- unsigned status;
+ unsigned status, pkt_len;
status = bdp->bd.cbd_sc;
if (status & BD_ENET_RX_EMPTY)