All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-06  2:25 ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

V3 has

1 dropped patch "net: fec: print more debug info in fec_timeout"
2 new patches
0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch

1 combined patch
0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch

The changes are noted on individual patches

My measured performance of this series is

before patch set
365 Mbits/sec Tx/407 RX

after patch set
374 Tx/427 Rx


Troy Kisky (16):
  net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
  net: fec: remove unused interrupt FEC_ENET_TS_TIMER
  net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
  net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
  net: fec: reduce interrupts
  net: fec: split off napi routine with 3 queues
  net: fec: don't clear all rx queue bits when just one is being checked
  net: fec: set cbd_sc without relying on previous value
  net: fec: eliminate calls to fec_enet_get_prevdesc
  net: fec: move restart test for efficiency
  net: fec: clear cbd_sc after transmission to help with debugging
  net: fec: dump all tx queues in fec_dump
  net: fec: detect tx int lost
  net: fec: create subroutine reset_tx_queue
  net: fec: call dma_unmap_single on mapped tx buffers at restart
  net: fec: don't set cbd_bufaddr unless no mapping error

 drivers/net/ethernet/freescale/fec.h      |  10 +-
 drivers/net/ethernet/freescale/fec_main.c | 410 ++++++++++++++++--------------
 2 files changed, 218 insertions(+), 202 deletions(-)

-- 
2.5.0

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-06  2:25 ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

V3 has

1 dropped patch "net: fec: print more debug info in fec_timeout"
2 new patches
0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch

1 combined patch
0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch

The changes are noted on individual patches

My measured performance of this series is

before patch set
365 Mbits/sec Tx/407 RX

after patch set
374 Tx/427 Rx


Troy Kisky (16):
  net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
  net: fec: remove unused interrupt FEC_ENET_TS_TIMER
  net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
  net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
  net: fec: reduce interrupts
  net: fec: split off napi routine with 3 queues
  net: fec: don't clear all rx queue bits when just one is being checked
  net: fec: set cbd_sc without relying on previous value
  net: fec: eliminate calls to fec_enet_get_prevdesc
  net: fec: move restart test for efficiency
  net: fec: clear cbd_sc after transmission to help with debugging
  net: fec: dump all tx queues in fec_dump
  net: fec: detect tx int lost
  net: fec: create subroutine reset_tx_queue
  net: fec: call dma_unmap_single on mapped tx buffers at restart
  net: fec: don't set cbd_bufaddr unless no mapping error

 drivers/net/ethernet/freescale/fec.h      |  10 +-
 drivers/net/ethernet/freescale/fec_main.c | 410 ++++++++++++++++--------------
 2 files changed, 218 insertions(+), 202 deletions(-)

-- 
2.5.0

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 01/16] net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

Before queue 0 was always checked if any queue caused an interrupt.
It is better to just mark queue 0 if queue 0 has caused an interrupt.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Fugang Duan <Fugang.duan@nxp.com>

---
v3: add Acked-by
---
 drivers/net/ethernet/freescale/fec_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 08243c2..a011719 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1534,14 +1534,14 @@ fec_enet_collect_events(struct fec_enet_private *fep, uint int_events)
 	if (int_events == 0)
 		return false;
 
-	if (int_events & FEC_ENET_RXF)
+	if (int_events & FEC_ENET_RXF_0)
 		fep->work_rx |= (1 << 2);
 	if (int_events & FEC_ENET_RXF_1)
 		fep->work_rx |= (1 << 0);
 	if (int_events & FEC_ENET_RXF_2)
 		fep->work_rx |= (1 << 1);
 
-	if (int_events & FEC_ENET_TXF)
+	if (int_events & FEC_ENET_TXF_0)
 		fep->work_tx |= (1 << 2);
 	if (int_events & FEC_ENET_TXF_1)
 		fep->work_tx |= (1 << 0);
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 01/16] net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

Before queue 0 was always checked if any queue caused an interrupt.
It is better to just mark queue 0 if queue 0 has caused an interrupt.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Fugang Duan <Fugang.duan@nxp.com>

---
v3: add Acked-by
---
 drivers/net/ethernet/freescale/fec_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 08243c2..a011719 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1534,14 +1534,14 @@ fec_enet_collect_events(struct fec_enet_private *fep, uint int_events)
 	if (int_events == 0)
 		return false;
 
-	if (int_events & FEC_ENET_RXF)
+	if (int_events & FEC_ENET_RXF_0)
 		fep->work_rx |= (1 << 2);
 	if (int_events & FEC_ENET_RXF_1)
 		fep->work_rx |= (1 << 0);
 	if (int_events & FEC_ENET_RXF_2)
 		fep->work_rx |= (1 << 1);
 
-	if (int_events & FEC_ENET_TXF)
+	if (int_events & FEC_ENET_TXF_0)
 		fep->work_tx |= (1 << 2);
 	if (int_events & FEC_ENET_TXF_1)
 		fep->work_tx |= (1 << 0);
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 02/16] net: fec: remove unused interrupt FEC_ENET_TS_TIMER
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

FEC_ENET_TS_TIMER is not checked in the interrupt routine
so there is no need to enable it.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: New patch

Frank Li said "TS_TIMER should never be triggered."
when discussing another patch.
---
 drivers/net/ethernet/freescale/fec.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 195122e..6dd0ba8 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -374,8 +374,8 @@ struct bufdesc_ex {
 #define FEC_ENET_TS_AVAIL       ((uint)0x00010000)
 #define FEC_ENET_TS_TIMER       ((uint)0x00008000)
 
-#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII | FEC_ENET_TS_TIMER)
-#define FEC_NAPI_IMASK	(FEC_ENET_MII | FEC_ENET_TS_TIMER)
+#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII)
+#define FEC_NAPI_IMASK	FEC_ENET_MII
 #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
 
 /* ENET interrupt coalescing macro define */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 02/16] net: fec: remove unused interrupt FEC_ENET_TS_TIMER
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

FEC_ENET_TS_TIMER is not checked in the interrupt routine
so there is no need to enable it.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: New patch

Frank Li said "TS_TIMER should never be triggered."
when discussing another patch.
---
 drivers/net/ethernet/freescale/fec.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 195122e..6dd0ba8 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -374,8 +374,8 @@ struct bufdesc_ex {
 #define FEC_ENET_TS_AVAIL       ((uint)0x00010000)
 #define FEC_ENET_TS_TIMER       ((uint)0x00008000)
 
-#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII | FEC_ENET_TS_TIMER)
-#define FEC_NAPI_IMASK	(FEC_ENET_MII | FEC_ENET_TS_TIMER)
+#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII)
+#define FEC_NAPI_IMASK	FEC_ENET_MII
 #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
 
 /* ENET interrupt coalescing macro define */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 03/16] net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

fec_ptp_check_pps_event will return 1 if FEC_T_TF_MASK caused
an interrupt. Don't return IRQ_NONE in this case.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: New patch, came from feedback from another patch.
---
 drivers/net/ethernet/freescale/fec_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index a011719..7993040 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1579,8 +1579,8 @@ fec_enet_interrupt(int irq, void *dev_id)
 	}
 
 	if (fep->ptp_clock)
-		fec_ptp_check_pps_event(fep);
-
+		if (fec_ptp_check_pps_event(fep))
+			ret = IRQ_HANDLED;
 	return ret;
 }
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 03/16] net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

fec_ptp_check_pps_event will return 1 if FEC_T_TF_MASK caused
an interrupt. Don't return IRQ_NONE in this case.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: New patch, came from feedback from another patch.
---
 drivers/net/ethernet/freescale/fec_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index a011719..7993040 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1579,8 +1579,8 @@ fec_enet_interrupt(int irq, void *dev_id)
 	}
 
 	if (fep->ptp_clock)
-		fec_ptp_check_pps_event(fep);
-
+		if (fec_ptp_check_pps_event(fep))
+			ret = IRQ_HANDLED;
 	return ret;
 }
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 04/16] net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

The queue_id is the qid member of struct bufdesc_prop.
Passing rxq/txq will allow the macro FEC_ENET_GET_QUQUE to be removed
in the next patch.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Fugang Duan <fugang.duan@nxp.com>

---
v3:
add Acked-by
combine with "net: fec: pass txq to fec_enet_tx_queue instead of queue_id"
reverted change that passed fep as a parameter
---
 drivers/net/ethernet/freescale/fec_main.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 7993040..b4d46f8 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1156,25 +1156,18 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
 	hwtstamps->hwtstamp = ns_to_ktime(ns);
 }
 
-static void
-fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
+static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 {
-	struct	fec_enet_private *fep;
+	struct  fec_enet_private *fep = netdev_priv(ndev);
 	struct bufdesc *bdp;
 	unsigned short status;
 	struct	sk_buff	*skb;
-	struct fec_enet_priv_tx_q *txq;
 	struct netdev_queue *nq;
 	int	index = 0;
 	int	entries_free;
 
-	fep = netdev_priv(ndev);
-
-	queue_id = FEC_ENET_GET_QUQUE(queue_id);
-
-	txq = fep->tx_queue[queue_id];
 	/* get next bdp of dirty_tx */
-	nq = netdev_get_tx_queue(ndev, queue_id);
+	nq = netdev_get_tx_queue(ndev, txq->bd.qid);
 	bdp = txq->dirty_tx;
 
 	/* get next bdp of dirty_tx */
@@ -1268,11 +1261,13 @@ static void
 fec_enet_tx(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct fec_enet_priv_tx_q *txq;
 	u16 queue_id;
 	/* First process class A queue, then Class B and Best Effort queue */
 	for_each_set_bit(queue_id, &fep->work_tx, FEC_ENET_MAX_TX_QS) {
 		clear_bit(queue_id, &fep->work_tx);
-		fec_enet_tx_queue(ndev, queue_id);
+		txq = fep->tx_queue[FEC_ENET_GET_QUQUE(queue_id)];
+		fec_txq(ndev, txq);
 	}
 	return;
 }
@@ -1328,11 +1323,10 @@ static bool fec_enet_copybreak(struct net_device *ndev, struct sk_buff **skb,
  * not been given to the system, we just set the empty indicator,
  * effectively tossing the packet.
  */
-static int
-fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
+		   int budget)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_enet_priv_rx_q *rxq;
 	struct bufdesc *bdp;
 	unsigned short status;
 	struct  sk_buff *skb_new = NULL;
@@ -1350,8 +1344,6 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
 #ifdef CONFIG_M532x
 	flush_cache_all();
 #endif
-	queue_id = FEC_ENET_GET_QUQUE(queue_id);
-	rxq = fep->rx_queue[queue_id];
 
 	/* First, grab all of the stats for the incoming packet.
 	 * These get messed up if we get called due to a busy condition.
@@ -1519,11 +1511,12 @@ fec_enet_rx(struct net_device *ndev, int budget)
 	int     pkt_received = 0;
 	u16	queue_id;
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct fec_enet_priv_rx_q *rxq;
 
 	for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
 		clear_bit(queue_id, &fep->work_rx);
-		pkt_received += fec_enet_rx_queue(ndev,
-					budget - pkt_received, queue_id);
+		rxq = fep->rx_queue[FEC_ENET_GET_QUQUE(queue_id)];
+		pkt_received += fec_rxq(ndev, rxq, budget - pkt_received);
 	}
 	return pkt_received;
 }
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 04/16] net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

The queue_id is the qid member of struct bufdesc_prop.
Passing rxq/txq will allow the macro FEC_ENET_GET_QUQUE to be removed
in the next patch.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Fugang Duan <fugang.duan@nxp.com>

---
v3:
add Acked-by
combine with "net: fec: pass txq to fec_enet_tx_queue instead of queue_id"
reverted change that passed fep as a parameter
---
 drivers/net/ethernet/freescale/fec_main.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 7993040..b4d46f8 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1156,25 +1156,18 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
 	hwtstamps->hwtstamp = ns_to_ktime(ns);
 }
 
-static void
-fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
+static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 {
-	struct	fec_enet_private *fep;
+	struct  fec_enet_private *fep = netdev_priv(ndev);
 	struct bufdesc *bdp;
 	unsigned short status;
 	struct	sk_buff	*skb;
-	struct fec_enet_priv_tx_q *txq;
 	struct netdev_queue *nq;
 	int	index = 0;
 	int	entries_free;
 
-	fep = netdev_priv(ndev);
-
-	queue_id = FEC_ENET_GET_QUQUE(queue_id);
-
-	txq = fep->tx_queue[queue_id];
 	/* get next bdp of dirty_tx */
-	nq = netdev_get_tx_queue(ndev, queue_id);
+	nq = netdev_get_tx_queue(ndev, txq->bd.qid);
 	bdp = txq->dirty_tx;
 
 	/* get next bdp of dirty_tx */
@@ -1268,11 +1261,13 @@ static void
 fec_enet_tx(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct fec_enet_priv_tx_q *txq;
 	u16 queue_id;
 	/* First process class A queue, then Class B and Best Effort queue */
 	for_each_set_bit(queue_id, &fep->work_tx, FEC_ENET_MAX_TX_QS) {
 		clear_bit(queue_id, &fep->work_tx);
-		fec_enet_tx_queue(ndev, queue_id);
+		txq = fep->tx_queue[FEC_ENET_GET_QUQUE(queue_id)];
+		fec_txq(ndev, txq);
 	}
 	return;
 }
@@ -1328,11 +1323,10 @@ static bool fec_enet_copybreak(struct net_device *ndev, struct sk_buff **skb,
  * not been given to the system, we just set the empty indicator,
  * effectively tossing the packet.
  */
-static int
-fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
+		   int budget)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_enet_priv_rx_q *rxq;
 	struct bufdesc *bdp;
 	unsigned short status;
 	struct  sk_buff *skb_new = NULL;
@@ -1350,8 +1344,6 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
 #ifdef CONFIG_M532x
 	flush_cache_all();
 #endif
-	queue_id = FEC_ENET_GET_QUQUE(queue_id);
-	rxq = fep->rx_queue[queue_id];
 
 	/* First, grab all of the stats for the incoming packet.
 	 * These get messed up if we get called due to a busy condition.
@@ -1519,11 +1511,12 @@ fec_enet_rx(struct net_device *ndev, int budget)
 	int     pkt_received = 0;
 	u16	queue_id;
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct fec_enet_priv_rx_q *rxq;
 
 	for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
 		clear_bit(queue_id, &fep->work_rx);
-		pkt_received += fec_enet_rx_queue(ndev,
-					budget - pkt_received, queue_id);
+		rxq = fep->rx_queue[FEC_ENET_GET_QUQUE(queue_id)];
+		pkt_received += fec_rxq(ndev, rxq, budget - pkt_received);
 	}
 	return pkt_received;
 }
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 05/16] net: fec: reduce interrupts
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

By clearing the NAPI interrupts in the NAPI routine
and not in the interrupt handler, we can reduce the
number of interrupts. We also don't need any status
variables as the registers are still valid.

Also, notice that if budget pkts are received, the
next call to fec_enet_rx_napi will now continue to
receive the previously pending packets.

To test that this actually reduces interrupts, try
this command before/after patch

cat /proc/interrupts |grep ether; \
ping -s2800 192.168.0.201 -f -c1000 ; \
cat /proc/interrupts |grep ether

For me, before this patch is 2996 interrupts.
After patch is 2010 interrupts.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3:
Fix introduced bug of checking for FEC_ENET_TS_TIMER
before calling fec_ptp_check_pps_event

Changed commit message to show measured changes.

Used netdev_info instead of pr_info.

Fugang Duan suggested splitting TX and RX into two NAPI
contexts, but that should be a separate patch as it
is unrelated to what this patch does.
---
 drivers/net/ethernet/freescale/fec.h      |   6 +-
 drivers/net/ethernet/freescale/fec_main.c | 118 +++++++++++-------------------
 2 files changed, 45 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 6dd0ba8..9d5bdc6 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -505,11 +505,7 @@ struct fec_enet_private {
 
 	unsigned int total_tx_ring_size;
 	unsigned int total_rx_ring_size;
-
-	unsigned long work_tx;
-	unsigned long work_rx;
-	unsigned long work_ts;
-	unsigned long work_mdio;
+	uint	events;
 
 	struct	platform_device *pdev;
 
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index b4d46f8..918ac82 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -70,8 +70,6 @@ static void fec_enet_itr_coal_init(struct net_device *ndev);
 
 #define DRIVER_NAME	"fec"
 
-#define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0))
-
 /* Pause frame feild and FIFO threshold */
 #define FEC_ENET_FCE	(1 << 5)
 #define FEC_ENET_RSEM_V	0x84
@@ -1257,21 +1255,6 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 		writel(0, txq->bd.reg_desc_active);
 }
 
-static void
-fec_enet_tx(struct net_device *ndev)
-{
-	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_enet_priv_tx_q *txq;
-	u16 queue_id;
-	/* First process class A queue, then Class B and Best Effort queue */
-	for_each_set_bit(queue_id, &fep->work_tx, FEC_ENET_MAX_TX_QS) {
-		clear_bit(queue_id, &fep->work_tx);
-		txq = fep->tx_queue[FEC_ENET_GET_QUQUE(queue_id)];
-		fec_txq(ndev, txq);
-	}
-	return;
-}
-
 static int
 fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff *skb)
 {
@@ -1505,70 +1488,34 @@ rx_processing_done:
 	return pkt_received;
 }
 
-static int
-fec_enet_rx(struct net_device *ndev, int budget)
-{
-	int     pkt_received = 0;
-	u16	queue_id;
-	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_enet_priv_rx_q *rxq;
-
-	for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
-		clear_bit(queue_id, &fep->work_rx);
-		rxq = fep->rx_queue[FEC_ENET_GET_QUQUE(queue_id)];
-		pkt_received += fec_rxq(ndev, rxq, budget - pkt_received);
-	}
-	return pkt_received;
-}
-
-static bool
-fec_enet_collect_events(struct fec_enet_private *fep, uint int_events)
-{
-	if (int_events == 0)
-		return false;
-
-	if (int_events & FEC_ENET_RXF_0)
-		fep->work_rx |= (1 << 2);
-	if (int_events & FEC_ENET_RXF_1)
-		fep->work_rx |= (1 << 0);
-	if (int_events & FEC_ENET_RXF_2)
-		fep->work_rx |= (1 << 1);
-
-	if (int_events & FEC_ENET_TXF_0)
-		fep->work_tx |= (1 << 2);
-	if (int_events & FEC_ENET_TXF_1)
-		fep->work_tx |= (1 << 0);
-	if (int_events & FEC_ENET_TXF_2)
-		fep->work_tx |= (1 << 1);
-
-	return true;
-}
-
 static irqreturn_t
 fec_enet_interrupt(int irq, void *dev_id)
 {
 	struct net_device *ndev = dev_id;
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	uint int_events;
 	irqreturn_t ret = IRQ_NONE;
+	uint eir = readl(fep->hwp + FEC_IEVENT);
+	uint int_events = eir & readl(fep->hwp + FEC_IMASK);
 
-	int_events = readl(fep->hwp + FEC_IEVENT);
-	writel(int_events, fep->hwp + FEC_IEVENT);
-	fec_enet_collect_events(fep, int_events);
-
-	if ((fep->work_tx || fep->work_rx) && fep->link) {
-		ret = IRQ_HANDLED;
-
+	if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
 		if (napi_schedule_prep(&fep->napi)) {
 			/* Disable the NAPI interrupts */
 			writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
 			__napi_schedule(&fep->napi);
+			int_events &= ~(FEC_ENET_RXF | FEC_ENET_TXF);
+			ret = IRQ_HANDLED;
+		} else {
+			fep->events |= int_events;
+			netdev_info(ndev, "couldn't schedule NAPI\n");
 		}
 	}
 
-	if (int_events & FEC_ENET_MII) {
+	if (int_events) {
 		ret = IRQ_HANDLED;
-		complete(&fep->mdio_done);
+		writel(int_events, fep->hwp + FEC_IEVENT);
+		if (int_events & FEC_ENET_MII) {
+			complete(&fep->mdio_done);
+		}
 	}
 
 	if (fep->ptp_clock)
@@ -1581,16 +1528,39 @@ 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;
-
-	pkts = fec_enet_rx(ndev, budget);
+	int pkts = 0;
+	uint events;
 
-	fec_enet_tx(ndev);
+	do {
+		events = readl(fep->hwp + FEC_IEVENT);
+		if (fep->events) {
+			events |= fep->events;
+			fep->events = 0;
+		}
+		events &= FEC_ENET_RXF | FEC_ENET_TXF;
+		if (!events) {
+			if (budget) {
+				napi_complete(napi);
+				writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+			}
+			return pkts;
+		}
 
-	if (pkts < budget) {
-		napi_complete(napi);
-		writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
-	}
+		writel(events, fep->hwp + FEC_IEVENT);
+		if (events & FEC_ENET_RXF_1)
+			pkts += fec_rxq(ndev, fep->rx_queue[1], budget - pkts);
+		if (events & FEC_ENET_RXF_2)
+			pkts += fec_rxq(ndev, fep->rx_queue[2], budget - pkts);
+		if (events & FEC_ENET_RXF_0)
+			pkts += fec_rxq(ndev, fep->rx_queue[0], budget - pkts);
+		if (events & FEC_ENET_TXF_1)
+			fec_txq(ndev, fep->tx_queue[1]);
+		if (events & FEC_ENET_TXF_2)
+			fec_txq(ndev, fep->tx_queue[2]);
+		if (events & FEC_ENET_TXF_0)
+			fec_txq(ndev, fep->tx_queue[0]);
+	} while (pkts < budget);
+	fep->events |= events & FEC_ENET_RXF;	/* save for next callback */
 	return pkts;
 }
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 05/16] net: fec: reduce interrupts
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

By clearing the NAPI interrupts in the NAPI routine
and not in the interrupt handler, we can reduce the
number of interrupts. We also don't need any status
variables as the registers are still valid.

Also, notice that if budget pkts are received, the
next call to fec_enet_rx_napi will now continue to
receive the previously pending packets.

To test that this actually reduces interrupts, try
this command before/after patch

cat /proc/interrupts |grep ether; \
ping -s2800 192.168.0.201 -f -c1000 ; \
cat /proc/interrupts |grep ether

For me, before this patch is 2996 interrupts.
After patch is 2010 interrupts.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3:
Fix introduced bug of checking for FEC_ENET_TS_TIMER
before calling fec_ptp_check_pps_event

Changed commit message to show measured changes.

Used netdev_info instead of pr_info.

Fugang Duan suggested splitting TX and RX into two NAPI
contexts, but that should be a separate patch as it
is unrelated to what this patch does.
---
 drivers/net/ethernet/freescale/fec.h      |   6 +-
 drivers/net/ethernet/freescale/fec_main.c | 118 +++++++++++-------------------
 2 files changed, 45 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 6dd0ba8..9d5bdc6 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -505,11 +505,7 @@ struct fec_enet_private {
 
 	unsigned int total_tx_ring_size;
 	unsigned int total_rx_ring_size;
-
-	unsigned long work_tx;
-	unsigned long work_rx;
-	unsigned long work_ts;
-	unsigned long work_mdio;
+	uint	events;
 
 	struct	platform_device *pdev;
 
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index b4d46f8..918ac82 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -70,8 +70,6 @@ static void fec_enet_itr_coal_init(struct net_device *ndev);
 
 #define DRIVER_NAME	"fec"
 
-#define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0))
-
 /* Pause frame feild and FIFO threshold */
 #define FEC_ENET_FCE	(1 << 5)
 #define FEC_ENET_RSEM_V	0x84
@@ -1257,21 +1255,6 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 		writel(0, txq->bd.reg_desc_active);
 }
 
-static void
-fec_enet_tx(struct net_device *ndev)
-{
-	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_enet_priv_tx_q *txq;
-	u16 queue_id;
-	/* First process class A queue, then Class B and Best Effort queue */
-	for_each_set_bit(queue_id, &fep->work_tx, FEC_ENET_MAX_TX_QS) {
-		clear_bit(queue_id, &fep->work_tx);
-		txq = fep->tx_queue[FEC_ENET_GET_QUQUE(queue_id)];
-		fec_txq(ndev, txq);
-	}
-	return;
-}
-
 static int
 fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff *skb)
 {
@@ -1505,70 +1488,34 @@ rx_processing_done:
 	return pkt_received;
 }
 
-static int
-fec_enet_rx(struct net_device *ndev, int budget)
-{
-	int     pkt_received = 0;
-	u16	queue_id;
-	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_enet_priv_rx_q *rxq;
-
-	for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
-		clear_bit(queue_id, &fep->work_rx);
-		rxq = fep->rx_queue[FEC_ENET_GET_QUQUE(queue_id)];
-		pkt_received += fec_rxq(ndev, rxq, budget - pkt_received);
-	}
-	return pkt_received;
-}
-
-static bool
-fec_enet_collect_events(struct fec_enet_private *fep, uint int_events)
-{
-	if (int_events == 0)
-		return false;
-
-	if (int_events & FEC_ENET_RXF_0)
-		fep->work_rx |= (1 << 2);
-	if (int_events & FEC_ENET_RXF_1)
-		fep->work_rx |= (1 << 0);
-	if (int_events & FEC_ENET_RXF_2)
-		fep->work_rx |= (1 << 1);
-
-	if (int_events & FEC_ENET_TXF_0)
-		fep->work_tx |= (1 << 2);
-	if (int_events & FEC_ENET_TXF_1)
-		fep->work_tx |= (1 << 0);
-	if (int_events & FEC_ENET_TXF_2)
-		fep->work_tx |= (1 << 1);
-
-	return true;
-}
-
 static irqreturn_t
 fec_enet_interrupt(int irq, void *dev_id)
 {
 	struct net_device *ndev = dev_id;
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	uint int_events;
 	irqreturn_t ret = IRQ_NONE;
+	uint eir = readl(fep->hwp + FEC_IEVENT);
+	uint int_events = eir & readl(fep->hwp + FEC_IMASK);
 
-	int_events = readl(fep->hwp + FEC_IEVENT);
-	writel(int_events, fep->hwp + FEC_IEVENT);
-	fec_enet_collect_events(fep, int_events);
-
-	if ((fep->work_tx || fep->work_rx) && fep->link) {
-		ret = IRQ_HANDLED;
-
+	if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
 		if (napi_schedule_prep(&fep->napi)) {
 			/* Disable the NAPI interrupts */
 			writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
 			__napi_schedule(&fep->napi);
+			int_events &= ~(FEC_ENET_RXF | FEC_ENET_TXF);
+			ret = IRQ_HANDLED;
+		} else {
+			fep->events |= int_events;
+			netdev_info(ndev, "couldn't schedule NAPI\n");
 		}
 	}
 
-	if (int_events & FEC_ENET_MII) {
+	if (int_events) {
 		ret = IRQ_HANDLED;
-		complete(&fep->mdio_done);
+		writel(int_events, fep->hwp + FEC_IEVENT);
+		if (int_events & FEC_ENET_MII) {
+			complete(&fep->mdio_done);
+		}
 	}
 
 	if (fep->ptp_clock)
@@ -1581,16 +1528,39 @@ 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;
-
-	pkts = fec_enet_rx(ndev, budget);
+	int pkts = 0;
+	uint events;
 
-	fec_enet_tx(ndev);
+	do {
+		events = readl(fep->hwp + FEC_IEVENT);
+		if (fep->events) {
+			events |= fep->events;
+			fep->events = 0;
+		}
+		events &= FEC_ENET_RXF | FEC_ENET_TXF;
+		if (!events) {
+			if (budget) {
+				napi_complete(napi);
+				writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+			}
+			return pkts;
+		}
 
-	if (pkts < budget) {
-		napi_complete(napi);
-		writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
-	}
+		writel(events, fep->hwp + FEC_IEVENT);
+		if (events & FEC_ENET_RXF_1)
+			pkts += fec_rxq(ndev, fep->rx_queue[1], budget - pkts);
+		if (events & FEC_ENET_RXF_2)
+			pkts += fec_rxq(ndev, fep->rx_queue[2], budget - pkts);
+		if (events & FEC_ENET_RXF_0)
+			pkts += fec_rxq(ndev, fep->rx_queue[0], budget - pkts);
+		if (events & FEC_ENET_TXF_1)
+			fec_txq(ndev, fep->tx_queue[1]);
+		if (events & FEC_ENET_TXF_2)
+			fec_txq(ndev, fep->tx_queue[2]);
+		if (events & FEC_ENET_TXF_0)
+			fec_txq(ndev, fep->tx_queue[0]);
+	} while (pkts < budget);
+	fep->events |= events & FEC_ENET_RXF;	/* save for next callback */
 	return pkts;
 }
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 06/16] net: fec: split off napi routine with 3 queues
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

If we only have 1 tx/rx queue, we need not check
the other queues.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: rebase changes only, fep is no longer passed as a parameter to
fec_rxq/fec_txq
---
 drivers/net/ethernet/freescale/fec_main.c | 39 +++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 918ac82..17140ea 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1524,7 +1524,7 @@ fec_enet_interrupt(int irq, void *dev_id)
 	return ret;
 }
 
-static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
+static int fec_enet_napi_q3(struct napi_struct *napi, int budget)
 {
 	struct net_device *ndev = napi->dev;
 	struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1564,6 +1564,39 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
 	return pkts;
 }
 
+static int fec_enet_napi_q1(struct napi_struct *napi, int budget)
+{
+	struct net_device *ndev = napi->dev;
+	struct fec_enet_private *fep = netdev_priv(ndev);
+	int pkts = 0;
+	uint events;
+
+	do {
+		events = readl(fep->hwp + FEC_IEVENT);
+		if (fep->events) {
+			events |= fep->events;
+			fep->events = 0;
+		}
+		events &= FEC_ENET_RXF_0 | FEC_ENET_TXF_0;
+		if (!events) {
+			if (budget) {
+				napi_complete(napi);
+				writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+			}
+			return pkts;
+		}
+
+		writel(events, fep->hwp + FEC_IEVENT);
+		if (events & FEC_ENET_RXF_0)
+			pkts += fec_rxq(ndev, fep->rx_queue[0],
+					budget - pkts);
+		if (events & FEC_ENET_TXF_0)
+			fec_txq(ndev, fep->tx_queue[0]);
+	} while (pkts < budget);
+	fep->events |= FEC_ENET_RXF_0;	/* save for next callback */
+	return pkts;
+}
+
 /* ------------------------------------------------------------------------- */
 static void fec_get_mac(struct net_device *ndev)
 {
@@ -3123,7 +3156,9 @@ static int fec_enet_init(struct net_device *ndev)
 	ndev->ethtool_ops = &fec_enet_ethtool_ops;
 
 	writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
-	netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT);
+	netif_napi_add(ndev, &fep->napi, (fep->num_rx_queues |
+		       fep->num_tx_queues) == 1 ? fec_enet_napi_q1 :
+		       fec_enet_napi_q3, NAPI_POLL_WEIGHT);
 
 	if (fep->quirks & FEC_QUIRK_HAS_VLAN)
 		/* enable hw VLAN support */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 06/16] net: fec: split off napi routine with 3 queues
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

If we only have 1 tx/rx queue, we need not check
the other queues.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: rebase changes only, fep is no longer passed as a parameter to
fec_rxq/fec_txq
---
 drivers/net/ethernet/freescale/fec_main.c | 39 +++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 918ac82..17140ea 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1524,7 +1524,7 @@ fec_enet_interrupt(int irq, void *dev_id)
 	return ret;
 }
 
-static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
+static int fec_enet_napi_q3(struct napi_struct *napi, int budget)
 {
 	struct net_device *ndev = napi->dev;
 	struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1564,6 +1564,39 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
 	return pkts;
 }
 
+static int fec_enet_napi_q1(struct napi_struct *napi, int budget)
+{
+	struct net_device *ndev = napi->dev;
+	struct fec_enet_private *fep = netdev_priv(ndev);
+	int pkts = 0;
+	uint events;
+
+	do {
+		events = readl(fep->hwp + FEC_IEVENT);
+		if (fep->events) {
+			events |= fep->events;
+			fep->events = 0;
+		}
+		events &= FEC_ENET_RXF_0 | FEC_ENET_TXF_0;
+		if (!events) {
+			if (budget) {
+				napi_complete(napi);
+				writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+			}
+			return pkts;
+		}
+
+		writel(events, fep->hwp + FEC_IEVENT);
+		if (events & FEC_ENET_RXF_0)
+			pkts += fec_rxq(ndev, fep->rx_queue[0],
+					budget - pkts);
+		if (events & FEC_ENET_TXF_0)
+			fec_txq(ndev, fep->tx_queue[0]);
+	} while (pkts < budget);
+	fep->events |= FEC_ENET_RXF_0;	/* save for next callback */
+	return pkts;
+}
+
 /* ------------------------------------------------------------------------- */
 static void fec_get_mac(struct net_device *ndev)
 {
@@ -3123,7 +3156,9 @@ static int fec_enet_init(struct net_device *ndev)
 	ndev->ethtool_ops = &fec_enet_ethtool_ops;
 
 	writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
-	netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT);
+	netif_napi_add(ndev, &fep->napi, (fep->num_rx_queues |
+		       fep->num_tx_queues) == 1 ? fec_enet_napi_q1 :
+		       fec_enet_napi_q3, NAPI_POLL_WEIGHT);
 
 	if (fep->quirks & FEC_QUIRK_HAS_VLAN)
 		/* enable hw VLAN support */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 07/16] net: fec: don't clear all rx queue bits when just one is being checked
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

FEC_ENET_RXF is 3 separate bits, we only check one queue
at a time. So, when the last queue is being checked, it is
bad to remove the interrupt on the 1st queue.

Also, since tx/rx interrupts are now cleared in the napi
routine and not the interrupt, it is not needed here any longer.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 17140ea..3cd0cdf 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1339,8 +1339,6 @@ static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
 			break;
 		pkt_received++;
 
-		writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
-
 		/* Check for errors. */
 		status ^= BD_ENET_RX_LAST;
 		if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 07/16] net: fec: don't clear all rx queue bits when just one is being checked
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

FEC_ENET_RXF is 3 separate bits, we only check one queue
at a time. So, when the last queue is being checked, it is
bad to remove the interrupt on the 1st queue.

Also, since tx/rx interrupts are now cleared in the napi
routine and not the interrupt, it is not needed here any longer.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 17140ea..3cd0cdf 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1339,8 +1339,6 @@ static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
 			break;
 		pkt_received++;
 
-		writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
-
 		/* Check for errors. */
 		status ^= BD_ENET_RX_LAST;
 		if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on previous value
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

Relying on the wrap bit of cdb_sc to stay valid once
initialized when the controller also writes to this byte
seems undesirable since we can easily know what the value
should be.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 38 +++++++++----------------------
 1 file changed, 11 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 3cd0cdf..21d2cd0 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -340,9 +340,8 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
 		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
 		ebdp = (struct bufdesc_ex *)bdp;
 
-		status = fec16_to_cpu(bdp->cbd_sc);
-		status &= ~BD_ENET_TX_STATS;
-		status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
+		status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+				((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
 		frag_len = skb_shinfo(skb)->frags[frag].size;
 
 		/* Handle the last BD specially */
@@ -436,8 +435,6 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
 	/* Fill in a Tx ring entry */
 	bdp = txq->bd.cur;
 	last_bdp = bdp;
-	status = fec16_to_cpu(bdp->cbd_sc);
-	status &= ~BD_ENET_TX_STATS;
 
 	/* Set buffer length and buffer pointer */
 	bufaddr = skb->data;
@@ -462,6 +459,8 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
 		return NETDEV_TX_OK;
 	}
 
+	status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+			((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
 	if (nr_frags) {
 		last_bdp = fec_enet_txq_submit_frag_skb(txq, skb, ndev);
 		if (IS_ERR(last_bdp)) {
@@ -512,7 +511,6 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
 	/* Send it on its way.  Tell FEC it's ready, interrupt when done,
 	 * it's the last BD of the frame, and to put the CRC on the end.
 	 */
-	status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
 	bdp->cbd_sc = cpu_to_fec16(status);
 
 	/* If this was the last BD in the ring, start at the beginning again. */
@@ -544,11 +542,6 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
 	unsigned int estatus = 0;
 	dma_addr_t addr;
 
-	status = fec16_to_cpu(bdp->cbd_sc);
-	status &= ~BD_ENET_TX_STATS;
-
-	status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
-
 	if (((unsigned long) data) & fep->tx_align ||
 		fep->quirks & FEC_QUIRK_SWAP_FRAME) {
 		memcpy(txq->tx_bounce[index], data, size);
@@ -578,15 +571,16 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
 		ebdp->cbd_esc = cpu_to_fec32(estatus);
 	}
 
+	status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+			((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
 	/* Handle the last BD specially */
 	if (last_tcp)
-		status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
+		status |= BD_ENET_TX_LAST;
 	if (is_last) {
 		status |= BD_ENET_TX_INTR;
 		if (fep->bufdesc_ex)
 			ebdp->cbd_esc |= cpu_to_fec32(BD_ENET_TX_INT);
 	}
-
 	bdp->cbd_sc = cpu_to_fec16(status);
 
 	return 0;
@@ -602,13 +596,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
 	struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
 	void *bufaddr;
 	unsigned long dmabuf;
-	unsigned short status;
 	unsigned int estatus = 0;
 
-	status = fec16_to_cpu(bdp->cbd_sc);
-	status &= ~BD_ENET_TX_STATS;
-	status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
-
 	bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
 	dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE;
 	if (((unsigned long)bufaddr) & fep->tx_align ||
@@ -641,8 +630,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
 		ebdp->cbd_esc = cpu_to_fec32(estatus);
 	}
 
-	bdp->cbd_sc = cpu_to_fec16(status);
-
+	bdp->cbd_sc = cpu_to_fec16(BD_ENET_TX_TC | BD_ENET_TX_READY |
+			((bdp == txq->bd.last) ? BD_SC_WRAP : 0));
 	return 0;
 }
 
@@ -1454,12 +1443,6 @@ static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
 		}
 
 rx_processing_done:
-		/* Clear the status flags for this buffer */
-		status &= ~BD_ENET_RX_STATS;
-
-		/* Mark the buffer empty */
-		status |= BD_ENET_RX_EMPTY;
-
 		if (fep->bufdesc_ex) {
 			struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
 
@@ -1471,7 +1454,8 @@ rx_processing_done:
 		 * performed before transferring ownership.
 		 */
 		wmb();
-		bdp->cbd_sc = cpu_to_fec16(status);
+		bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
+				((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
 
 		/* Update BD pointer to next entry */
 		bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on previous value
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

Relying on the wrap bit of cdb_sc to stay valid once
initialized when the controller also writes to this byte
seems undesirable since we can easily know what the value
should be.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 38 +++++++++----------------------
 1 file changed, 11 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 3cd0cdf..21d2cd0 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -340,9 +340,8 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
 		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
 		ebdp = (struct bufdesc_ex *)bdp;
 
-		status = fec16_to_cpu(bdp->cbd_sc);
-		status &= ~BD_ENET_TX_STATS;
-		status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
+		status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+				((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
 		frag_len = skb_shinfo(skb)->frags[frag].size;
 
 		/* Handle the last BD specially */
@@ -436,8 +435,6 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
 	/* Fill in a Tx ring entry */
 	bdp = txq->bd.cur;
 	last_bdp = bdp;
-	status = fec16_to_cpu(bdp->cbd_sc);
-	status &= ~BD_ENET_TX_STATS;
 
 	/* Set buffer length and buffer pointer */
 	bufaddr = skb->data;
@@ -462,6 +459,8 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
 		return NETDEV_TX_OK;
 	}
 
+	status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+			((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
 	if (nr_frags) {
 		last_bdp = fec_enet_txq_submit_frag_skb(txq, skb, ndev);
 		if (IS_ERR(last_bdp)) {
@@ -512,7 +511,6 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
 	/* Send it on its way.  Tell FEC it's ready, interrupt when done,
 	 * it's the last BD of the frame, and to put the CRC on the end.
 	 */
-	status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
 	bdp->cbd_sc = cpu_to_fec16(status);
 
 	/* If this was the last BD in the ring, start at the beginning again. */
@@ -544,11 +542,6 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
 	unsigned int estatus = 0;
 	dma_addr_t addr;
 
-	status = fec16_to_cpu(bdp->cbd_sc);
-	status &= ~BD_ENET_TX_STATS;
-
-	status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
-
 	if (((unsigned long) data) & fep->tx_align ||
 		fep->quirks & FEC_QUIRK_SWAP_FRAME) {
 		memcpy(txq->tx_bounce[index], data, size);
@@ -578,15 +571,16 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
 		ebdp->cbd_esc = cpu_to_fec32(estatus);
 	}
 
+	status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+			((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
 	/* Handle the last BD specially */
 	if (last_tcp)
-		status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
+		status |= BD_ENET_TX_LAST;
 	if (is_last) {
 		status |= BD_ENET_TX_INTR;
 		if (fep->bufdesc_ex)
 			ebdp->cbd_esc |= cpu_to_fec32(BD_ENET_TX_INT);
 	}
-
 	bdp->cbd_sc = cpu_to_fec16(status);
 
 	return 0;
@@ -602,13 +596,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
 	struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
 	void *bufaddr;
 	unsigned long dmabuf;
-	unsigned short status;
 	unsigned int estatus = 0;
 
-	status = fec16_to_cpu(bdp->cbd_sc);
-	status &= ~BD_ENET_TX_STATS;
-	status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
-
 	bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
 	dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE;
 	if (((unsigned long)bufaddr) & fep->tx_align ||
@@ -641,8 +630,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
 		ebdp->cbd_esc = cpu_to_fec32(estatus);
 	}
 
-	bdp->cbd_sc = cpu_to_fec16(status);
-
+	bdp->cbd_sc = cpu_to_fec16(BD_ENET_TX_TC | BD_ENET_TX_READY |
+			((bdp == txq->bd.last) ? BD_SC_WRAP : 0));
 	return 0;
 }
 
@@ -1454,12 +1443,6 @@ static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
 		}
 
 rx_processing_done:
-		/* Clear the status flags for this buffer */
-		status &= ~BD_ENET_RX_STATS;
-
-		/* Mark the buffer empty */
-		status |= BD_ENET_RX_EMPTY;
-
 		if (fep->bufdesc_ex) {
 			struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
 
@@ -1471,7 +1454,8 @@ rx_processing_done:
 		 * performed before transferring ownership.
 		 */
 		wmb();
-		bdp->cbd_sc = cpu_to_fec16(status);
+		bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
+				((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
 
 		/* Update BD pointer to next entry */
 		bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 09/16] net: fec: eliminate calls to fec_enet_get_prevdesc
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

Eliminating calls to fec_enet_get_prevdesc shrinks
the code a little.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: Change commit message

s/unsigned status/unsigned int status/ as requested
---
 drivers/net/ethernet/freescale/fec_main.c | 37 +++++++++----------------------
 1 file changed, 11 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 21d2cd0..349fda1 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -758,6 +758,7 @@ static void fec_enet_bd_init(struct net_device *dev)
 	struct bufdesc *bdp;
 	unsigned int i;
 	unsigned int q;
+	unsigned int status;
 
 	for (q = 0; q < fep->num_rx_queues; q++) {
 		/* Initialize the receive buffer descriptors. */
@@ -765,19 +766,13 @@ static void fec_enet_bd_init(struct net_device *dev)
 		bdp = rxq->bd.base;
 
 		for (i = 0; i < rxq->bd.ring_size; i++) {
-
 			/* Initialize the BD for every fragment in the page. */
-			if (bdp->cbd_bufaddr)
-				bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY);
-			else
-				bdp->cbd_sc = cpu_to_fec16(0);
+			status = bdp->cbd_bufaddr ? BD_ENET_RX_EMPTY : 0;
+			if (bdp == rxq->bd.last)
+				status |= BD_SC_WRAP;
+			bdp->cbd_sc = cpu_to_fec16(status);
 			bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
 		}
-
-		/* Set the last buffer to wrap */
-		bdp = fec_enet_get_prevdesc(bdp, &rxq->bd);
-		bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
-
 		rxq->bd.cur = rxq->bd.base;
 	}
 
@@ -789,18 +784,16 @@ static void fec_enet_bd_init(struct net_device *dev)
 
 		for (i = 0; i < txq->bd.ring_size; i++) {
 			/* Initialize the BD for every fragment in the page. */
-			bdp->cbd_sc = cpu_to_fec16(0);
 			if (txq->tx_skbuff[i]) {
 				dev_kfree_skb_any(txq->tx_skbuff[i]);
 				txq->tx_skbuff[i] = NULL;
 			}
 			bdp->cbd_bufaddr = cpu_to_fec32(0);
+			bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+					BD_SC_WRAP : 0);
 			bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
 		}
-
-		/* Set the last buffer to wrap */
 		bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
-		bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
 		txq->dirty_tx = bdp;
 	}
 }
@@ -2717,19 +2710,16 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
 		}
 
 		rxq->rx_skbuff[i] = skb;
-		bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY);
 
 		if (fep->bufdesc_ex) {
 			struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
 			ebdp->cbd_esc = cpu_to_fec32(BD_ENET_RX_INT);
 		}
+		bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
+				((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
 
 		bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
 	}
-
-	/* Set the last buffer to wrap. */
-	bdp = fec_enet_get_prevdesc(bdp, &rxq->bd);
-	bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
 	return 0;
 
  err_alloc:
@@ -2752,21 +2742,16 @@ fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
 		if (!txq->tx_bounce[i])
 			goto err_alloc;
 
-		bdp->cbd_sc = cpu_to_fec16(0);
 		bdp->cbd_bufaddr = cpu_to_fec32(0);
 
 		if (fep->bufdesc_ex) {
 			struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
 			ebdp->cbd_esc = cpu_to_fec32(BD_ENET_TX_INT);
 		}
-
+		bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+				BD_SC_WRAP : 0);
 		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
 	}
-
-	/* Set the last buffer to wrap. */
-	bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
-	bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
-
 	return 0;
 
  err_alloc:
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 09/16] net: fec: eliminate calls to fec_enet_get_prevdesc
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

Eliminating calls to fec_enet_get_prevdesc shrinks
the code a little.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: Change commit message

s/unsigned status/unsigned int status/ as requested
---
 drivers/net/ethernet/freescale/fec_main.c | 37 +++++++++----------------------
 1 file changed, 11 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 21d2cd0..349fda1 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -758,6 +758,7 @@ static void fec_enet_bd_init(struct net_device *dev)
 	struct bufdesc *bdp;
 	unsigned int i;
 	unsigned int q;
+	unsigned int status;
 
 	for (q = 0; q < fep->num_rx_queues; q++) {
 		/* Initialize the receive buffer descriptors. */
@@ -765,19 +766,13 @@ static void fec_enet_bd_init(struct net_device *dev)
 		bdp = rxq->bd.base;
 
 		for (i = 0; i < rxq->bd.ring_size; i++) {
-
 			/* Initialize the BD for every fragment in the page. */
-			if (bdp->cbd_bufaddr)
-				bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY);
-			else
-				bdp->cbd_sc = cpu_to_fec16(0);
+			status = bdp->cbd_bufaddr ? BD_ENET_RX_EMPTY : 0;
+			if (bdp == rxq->bd.last)
+				status |= BD_SC_WRAP;
+			bdp->cbd_sc = cpu_to_fec16(status);
 			bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
 		}
-
-		/* Set the last buffer to wrap */
-		bdp = fec_enet_get_prevdesc(bdp, &rxq->bd);
-		bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
-
 		rxq->bd.cur = rxq->bd.base;
 	}
 
@@ -789,18 +784,16 @@ static void fec_enet_bd_init(struct net_device *dev)
 
 		for (i = 0; i < txq->bd.ring_size; i++) {
 			/* Initialize the BD for every fragment in the page. */
-			bdp->cbd_sc = cpu_to_fec16(0);
 			if (txq->tx_skbuff[i]) {
 				dev_kfree_skb_any(txq->tx_skbuff[i]);
 				txq->tx_skbuff[i] = NULL;
 			}
 			bdp->cbd_bufaddr = cpu_to_fec32(0);
+			bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+					BD_SC_WRAP : 0);
 			bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
 		}
-
-		/* Set the last buffer to wrap */
 		bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
-		bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
 		txq->dirty_tx = bdp;
 	}
 }
@@ -2717,19 +2710,16 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
 		}
 
 		rxq->rx_skbuff[i] = skb;
-		bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY);
 
 		if (fep->bufdesc_ex) {
 			struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
 			ebdp->cbd_esc = cpu_to_fec32(BD_ENET_RX_INT);
 		}
+		bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
+				((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
 
 		bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
 	}
-
-	/* Set the last buffer to wrap. */
-	bdp = fec_enet_get_prevdesc(bdp, &rxq->bd);
-	bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
 	return 0;
 
  err_alloc:
@@ -2752,21 +2742,16 @@ fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
 		if (!txq->tx_bounce[i])
 			goto err_alloc;
 
-		bdp->cbd_sc = cpu_to_fec16(0);
 		bdp->cbd_bufaddr = cpu_to_fec32(0);
 
 		if (fep->bufdesc_ex) {
 			struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
 			ebdp->cbd_esc = cpu_to_fec32(BD_ENET_TX_INT);
 		}
-
+		bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+				BD_SC_WRAP : 0);
 		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
 	}
-
-	/* Set the last buffer to wrap. */
-	bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
-	bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
-
 	return 0;
 
  err_alloc:
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 10/16] net: fec: move restart test for efficiency
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

Move restart test to earlier in fec_txq() which saves one comparison.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 349fda1..a2a9dca 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1157,8 +1157,13 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 		/* Order the load of bd.cur and cbd_sc */
 		rmb();
 		status = fec16_to_cpu(READ_ONCE(bdp->cbd_sc));
-		if (status & BD_ENET_TX_READY)
+		if (status & BD_ENET_TX_READY) {
+			if (!readl(txq->bd.reg_desc_active)) {
+				/* ERR006358 has hit, restart tx */
+				writel(0, txq->bd.reg_desc_active);
+			}
 			break;
+		}
 
 		index = fec_enet_get_bd_index(bdp, &txq->bd);
 
@@ -1230,11 +1235,6 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 				netif_tx_wake_queue(nq);
 		}
 	}
-
-	/* ERR006538: Keep the transmitter going */
-	if (bdp != txq->bd.cur &&
-	    readl(txq->bd.reg_desc_active) == 0)
-		writel(0, txq->bd.reg_desc_active);
 }
 
 static int
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 10/16] net: fec: move restart test for efficiency
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

Move restart test to earlier in fec_txq() which saves one comparison.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 349fda1..a2a9dca 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1157,8 +1157,13 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 		/* Order the load of bd.cur and cbd_sc */
 		rmb();
 		status = fec16_to_cpu(READ_ONCE(bdp->cbd_sc));
-		if (status & BD_ENET_TX_READY)
+		if (status & BD_ENET_TX_READY) {
+			if (!readl(txq->bd.reg_desc_active)) {
+				/* ERR006358 has hit, restart tx */
+				writel(0, txq->bd.reg_desc_active);
+			}
 			break;
+		}
 
 		index = fec_enet_get_bd_index(bdp, &txq->bd);
 
@@ -1230,11 +1235,6 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 				netif_tx_wake_queue(nq);
 		}
 	}
-
-	/* ERR006538: Keep the transmitter going */
-	if (bdp != txq->bd.cur &&
-	    readl(txq->bd.reg_desc_active) == 0)
-		writel(0, txq->bd.reg_desc_active);
 }
 
 static int
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 11/16] net: fec: clear cbd_sc after transmission to help with debugging
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

When the tx queue is dumped, it is easier to see that this
entry is idle if cbd_sc is cleared after transmission.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index a2a9dca..f96ea97 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1164,6 +1164,8 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 			}
 			break;
 		}
+		bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+					   BD_SC_WRAP : 0);
 
 		index = fec_enet_get_bd_index(bdp, &txq->bd);
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 11/16] net: fec: clear cbd_sc after transmission to help with debugging
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

When the tx queue is dumped, it is easier to see that this
entry is idle if cbd_sc is cleared after transmission.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index a2a9dca..f96ea97 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1164,6 +1164,8 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
 			}
 			break;
 		}
+		bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+					   BD_SC_WRAP : 0);
 
 		index = fec_enet_get_bd_index(bdp, &txq->bd);
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 12/16] net: fec: dump all tx queues in fec_dump
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

Dump all tx queues, not just queue 0.
Also, disable fec interrupts first.
The interrupts will be reenabled in fec_restart.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: no change
---
 drivers/net/ethernet/freescale/fec_main.c | 40 +++++++++++++++++--------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index f96ea97..be875fd 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -271,28 +271,32 @@ static void swap_buffer2(void *dst_buf, void *src_buf, int len)
 static void fec_dump(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct bufdesc *bdp;
-	struct fec_enet_priv_tx_q *txq;
-	int index = 0;
+	int i;
 
+	/* Disable all FEC interrupts */
+	writel(0, fep->hwp + FEC_IMASK);
 	netdev_info(ndev, "TX ring dump\n");
 	pr_info("Nr     SC     addr       len  SKB\n");
 
-	txq = fep->tx_queue[0];
-	bdp = txq->bd.base;
-
-	do {
-		pr_info("%3u %c%c 0x%04x 0x%08x %4u %p\n",
-			index,
-			bdp == txq->bd.cur ? 'S' : ' ',
-			bdp == txq->dirty_tx ? 'H' : ' ',
-			fec16_to_cpu(bdp->cbd_sc),
-			fec32_to_cpu(bdp->cbd_bufaddr),
-			fec16_to_cpu(bdp->cbd_datlen),
-			txq->tx_skbuff[index]);
-		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
-		index++;
-	} while (bdp != txq->bd.base);
+	for (i = 0; i < fep->num_tx_queues; i++) {
+		struct fec_enet_priv_tx_q *txq = fep->tx_queue[i];
+		struct bufdesc *bdp = txq->bd.base;
+		int index = 0;
+
+		pr_info("tx queue %d\n", i);
+		do {
+			pr_info("%3u %c%c 0x%04x 0x%08x %4u %p\n",
+				index,
+				bdp == txq->bd.cur ? 'S' : ' ',
+				bdp == txq->dirty_tx ? 'H' : ' ',
+				fec16_to_cpu(bdp->cbd_sc),
+				fec32_to_cpu(bdp->cbd_bufaddr),
+				fec16_to_cpu(bdp->cbd_datlen),
+				txq->tx_skbuff[index]);
+			bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+			index++;
+		} while (bdp != txq->bd.base);
+	}
 }
 
 static inline bool is_ipv4_pkt(struct sk_buff *skb)
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 12/16] net: fec: dump all tx queues in fec_dump
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

Dump all tx queues, not just queue 0.
Also, disable fec interrupts first.
The interrupts will be reenabled in fec_restart.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: no change
---
 drivers/net/ethernet/freescale/fec_main.c | 40 +++++++++++++++++--------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index f96ea97..be875fd 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -271,28 +271,32 @@ static void swap_buffer2(void *dst_buf, void *src_buf, int len)
 static void fec_dump(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct bufdesc *bdp;
-	struct fec_enet_priv_tx_q *txq;
-	int index = 0;
+	int i;
 
+	/* Disable all FEC interrupts */
+	writel(0, fep->hwp + FEC_IMASK);
 	netdev_info(ndev, "TX ring dump\n");
 	pr_info("Nr     SC     addr       len  SKB\n");
 
-	txq = fep->tx_queue[0];
-	bdp = txq->bd.base;
-
-	do {
-		pr_info("%3u %c%c 0x%04x 0x%08x %4u %p\n",
-			index,
-			bdp == txq->bd.cur ? 'S' : ' ',
-			bdp == txq->dirty_tx ? 'H' : ' ',
-			fec16_to_cpu(bdp->cbd_sc),
-			fec32_to_cpu(bdp->cbd_bufaddr),
-			fec16_to_cpu(bdp->cbd_datlen),
-			txq->tx_skbuff[index]);
-		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
-		index++;
-	} while (bdp != txq->bd.base);
+	for (i = 0; i < fep->num_tx_queues; i++) {
+		struct fec_enet_priv_tx_q *txq = fep->tx_queue[i];
+		struct bufdesc *bdp = txq->bd.base;
+		int index = 0;
+
+		pr_info("tx queue %d\n", i);
+		do {
+			pr_info("%3u %c%c 0x%04x 0x%08x %4u %p\n",
+				index,
+				bdp == txq->bd.cur ? 'S' : ' ',
+				bdp == txq->dirty_tx ? 'H' : ' ',
+				fec16_to_cpu(bdp->cbd_sc),
+				fec32_to_cpu(bdp->cbd_bufaddr),
+				fec16_to_cpu(bdp->cbd_datlen),
+				txq->tx_skbuff[index]);
+			bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+			index++;
+		} while (bdp != txq->bd.base);
+	}
 }
 
 static inline bool is_ipv4_pkt(struct sk_buff *skb)
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 13/16] net: fec: detect tx int lost
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:25   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

If a tx int is lost, no need to reset
the fec. Just mark the event and call napi_schedule.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: no change
---
 drivers/net/ethernet/freescale/fec_main.c | 38 ++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index be875fd..445443d 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1094,14 +1094,50 @@ fec_stop(struct net_device *ndev)
 	}
 }
 
+static const uint txint_flags[] = {
+	FEC_ENET_TXF_0, FEC_ENET_TXF_1, FEC_ENET_TXF_2
+};
 
 static void
 fec_timeout(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct bufdesc *bdp;
+	unsigned short status;
+	int i;
+	uint events = 0;
 
-	fec_dump(ndev);
+	for (i = 0; i < fep->num_tx_queues; i++) {
+		struct fec_enet_priv_tx_q *txq = fep->tx_queue[i];
+		int index;
+		struct sk_buff *skb = NULL;
 
+		bdp = txq->dirty_tx;
+		while (1) {
+			bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+			if (bdp == txq->bd.cur)
+				break;
+			index = fec_enet_get_bd_index(bdp, &txq->bd);
+			skb = txq->tx_skbuff[index];
+			if (skb) {
+				status = fec16_to_cpu(bdp->cbd_sc);
+				if ((status & BD_ENET_TX_READY) == 0)
+					events |= txint_flags[i];
+				break;
+			}
+		}
+	}
+	if (events) {
+		fep->events |= events;
+		/* Disable the RX/TX interrupt */
+		writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
+		napi_schedule(&fep->napi);
+		netif_wake_queue(fep->netdev);
+		pr_err("%s: tx int lost\n", __func__);
+		return;
+	}
+
+	fec_dump(ndev);
 	ndev->stats.tx_errors++;
 
 	schedule_work(&fep->tx_timeout_work);
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 13/16] net: fec: detect tx int lost
@ 2016-04-06  2:25   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

If a tx int is lost, no need to reset
the fec. Just mark the event and call napi_schedule.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: no change
---
 drivers/net/ethernet/freescale/fec_main.c | 38 ++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index be875fd..445443d 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1094,14 +1094,50 @@ fec_stop(struct net_device *ndev)
 	}
 }
 
+static const uint txint_flags[] = {
+	FEC_ENET_TXF_0, FEC_ENET_TXF_1, FEC_ENET_TXF_2
+};
 
 static void
 fec_timeout(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct bufdesc *bdp;
+	unsigned short status;
+	int i;
+	uint events = 0;
 
-	fec_dump(ndev);
+	for (i = 0; i < fep->num_tx_queues; i++) {
+		struct fec_enet_priv_tx_q *txq = fep->tx_queue[i];
+		int index;
+		struct sk_buff *skb = NULL;
 
+		bdp = txq->dirty_tx;
+		while (1) {
+			bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+			if (bdp == txq->bd.cur)
+				break;
+			index = fec_enet_get_bd_index(bdp, &txq->bd);
+			skb = txq->tx_skbuff[index];
+			if (skb) {
+				status = fec16_to_cpu(bdp->cbd_sc);
+				if ((status & BD_ENET_TX_READY) == 0)
+					events |= txint_flags[i];
+				break;
+			}
+		}
+	}
+	if (events) {
+		fep->events |= events;
+		/* Disable the RX/TX interrupt */
+		writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
+		napi_schedule(&fep->napi);
+		netif_wake_queue(fep->netdev);
+		pr_err("%s: tx int lost\n", __func__);
+		return;
+	}
+
+	fec_dump(ndev);
 	ndev->stats.tx_errors++;
 
 	schedule_work(&fep->tx_timeout_work);
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 14/16] net: fec: create subroutine reset_tx_queue
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:26   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:26 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

Create subroutine reset_tx_queue to have one place
to release any queued tx skbs.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 50 +++++++++++++++----------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 445443d..a38acf2 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -752,12 +752,33 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	return NETDEV_TX_OK;
 }
 
+static void reset_tx_queue(struct fec_enet_private *fep,
+			   struct fec_enet_priv_tx_q *txq)
+{
+	struct bufdesc *bdp = txq->bd.base;
+	unsigned int i;
+
+	txq->bd.cur = bdp;
+	for (i = 0; i < txq->bd.ring_size; i++) {
+		/* Initialize the BD for every fragment in the page. */
+		if (txq->tx_skbuff[i]) {
+			dev_kfree_skb_any(txq->tx_skbuff[i]);
+			txq->tx_skbuff[i] = NULL;
+		}
+		bdp->cbd_bufaddr = cpu_to_fec32(0);
+		bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+					   BD_SC_WRAP : 0);
+		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+	}
+	bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
+	txq->dirty_tx = bdp;
+}
+
 /* Init RX & TX buffer descriptors
  */
 static void fec_enet_bd_init(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
-	struct fec_enet_priv_tx_q *txq;
 	struct fec_enet_priv_rx_q *rxq;
 	struct bufdesc *bdp;
 	unsigned int i;
@@ -780,26 +801,8 @@ static void fec_enet_bd_init(struct net_device *dev)
 		rxq->bd.cur = rxq->bd.base;
 	}
 
-	for (q = 0; q < fep->num_tx_queues; q++) {
-		/* ...and the same for transmit */
-		txq = fep->tx_queue[q];
-		bdp = txq->bd.base;
-		txq->bd.cur = bdp;
-
-		for (i = 0; i < txq->bd.ring_size; i++) {
-			/* Initialize the BD for every fragment in the page. */
-			if (txq->tx_skbuff[i]) {
-				dev_kfree_skb_any(txq->tx_skbuff[i]);
-				txq->tx_skbuff[i] = NULL;
-			}
-			bdp->cbd_bufaddr = cpu_to_fec32(0);
-			bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
-					BD_SC_WRAP : 0);
-			bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
-		}
-		bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
-		txq->dirty_tx = bdp;
-	}
+	for (q = 0; q < fep->num_tx_queues; q++)
+		reset_tx_queue(fep, fep->tx_queue[q]);
 }
 
 static void fec_enet_active_rxring(struct net_device *ndev)
@@ -2648,13 +2651,10 @@ static void fec_enet_free_buffers(struct net_device *ndev)
 
 	for (q = 0; q < fep->num_tx_queues; q++) {
 		txq = fep->tx_queue[q];
-		bdp = txq->bd.base;
+		reset_tx_queue(fep, txq);
 		for (i = 0; i < txq->bd.ring_size; i++) {
 			kfree(txq->tx_bounce[i]);
 			txq->tx_bounce[i] = NULL;
-			skb = txq->tx_skbuff[i];
-			txq->tx_skbuff[i] = NULL;
-			dev_kfree_skb(skb);
 		}
 	}
 }
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 14/16] net: fec: create subroutine reset_tx_queue
@ 2016-04-06  2:26   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:26 UTC (permalink / raw)
  To: linux-arm-kernel

Create subroutine reset_tx_queue to have one place
to release any queued tx skbs.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: change commit message
---
 drivers/net/ethernet/freescale/fec_main.c | 50 +++++++++++++++----------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 445443d..a38acf2 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -752,12 +752,33 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	return NETDEV_TX_OK;
 }
 
+static void reset_tx_queue(struct fec_enet_private *fep,
+			   struct fec_enet_priv_tx_q *txq)
+{
+	struct bufdesc *bdp = txq->bd.base;
+	unsigned int i;
+
+	txq->bd.cur = bdp;
+	for (i = 0; i < txq->bd.ring_size; i++) {
+		/* Initialize the BD for every fragment in the page. */
+		if (txq->tx_skbuff[i]) {
+			dev_kfree_skb_any(txq->tx_skbuff[i]);
+			txq->tx_skbuff[i] = NULL;
+		}
+		bdp->cbd_bufaddr = cpu_to_fec32(0);
+		bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+					   BD_SC_WRAP : 0);
+		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+	}
+	bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
+	txq->dirty_tx = bdp;
+}
+
 /* Init RX & TX buffer descriptors
  */
 static void fec_enet_bd_init(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
-	struct fec_enet_priv_tx_q *txq;
 	struct fec_enet_priv_rx_q *rxq;
 	struct bufdesc *bdp;
 	unsigned int i;
@@ -780,26 +801,8 @@ static void fec_enet_bd_init(struct net_device *dev)
 		rxq->bd.cur = rxq->bd.base;
 	}
 
-	for (q = 0; q < fep->num_tx_queues; q++) {
-		/* ...and the same for transmit */
-		txq = fep->tx_queue[q];
-		bdp = txq->bd.base;
-		txq->bd.cur = bdp;
-
-		for (i = 0; i < txq->bd.ring_size; i++) {
-			/* Initialize the BD for every fragment in the page. */
-			if (txq->tx_skbuff[i]) {
-				dev_kfree_skb_any(txq->tx_skbuff[i]);
-				txq->tx_skbuff[i] = NULL;
-			}
-			bdp->cbd_bufaddr = cpu_to_fec32(0);
-			bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
-					BD_SC_WRAP : 0);
-			bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
-		}
-		bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
-		txq->dirty_tx = bdp;
-	}
+	for (q = 0; q < fep->num_tx_queues; q++)
+		reset_tx_queue(fep, fep->tx_queue[q]);
 }
 
 static void fec_enet_active_rxring(struct net_device *ndev)
@@ -2648,13 +2651,10 @@ static void fec_enet_free_buffers(struct net_device *ndev)
 
 	for (q = 0; q < fep->num_tx_queues; q++) {
 		txq = fep->tx_queue[q];
-		bdp = txq->bd.base;
+		reset_tx_queue(fep, txq);
 		for (i = 0; i < txq->bd.ring_size; i++) {
 			kfree(txq->tx_bounce[i]);
 			txq->tx_bounce[i] = NULL;
-			skb = txq->tx_skbuff[i];
-			txq->tx_skbuff[i] = NULL;
-			dev_kfree_skb(skb);
 		}
 	}
 }
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 15/16] net: fec: call dma_unmap_single on mapped tx buffers at restart
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:26   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:26 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

Make sure any pending tx buffers are unmapped when the
fec is restarted.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: no change
---
 drivers/net/ethernet/freescale/fec_main.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index a38acf2..101d820 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -404,6 +404,7 @@ dma_mapping_error:
 		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
 		dma_unmap_single(&fep->pdev->dev, fec32_to_cpu(bdp->cbd_bufaddr),
 				 fec16_to_cpu(bdp->cbd_datlen), DMA_TO_DEVICE);
+		bdp->cbd_bufaddr = cpu_to_fec32(0);
 	}
 	return ERR_PTR(-ENOMEM);
 }
@@ -761,11 +762,18 @@ static void reset_tx_queue(struct fec_enet_private *fep,
 	txq->bd.cur = bdp;
 	for (i = 0; i < txq->bd.ring_size; i++) {
 		/* Initialize the BD for every fragment in the page. */
+		if (bdp->cbd_bufaddr) {
+			if (!IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
+				dma_unmap_single(&fep->pdev->dev,
+						 fec32_to_cpu(bdp->cbd_bufaddr),
+						 fec16_to_cpu(bdp->cbd_datlen),
+						 DMA_TO_DEVICE);
+			bdp->cbd_bufaddr = cpu_to_fec32(0);
+		}
 		if (txq->tx_skbuff[i]) {
 			dev_kfree_skb_any(txq->tx_skbuff[i]);
 			txq->tx_skbuff[i] = NULL;
 		}
-		bdp->cbd_bufaddr = cpu_to_fec32(0);
 		bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
 					   BD_SC_WRAP : 0);
 		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
@@ -2643,6 +2651,7 @@ static void fec_enet_free_buffers(struct net_device *ndev)
 						 fec32_to_cpu(bdp->cbd_bufaddr),
 						 FEC_ENET_RX_FRSIZE - fep->rx_align,
 						 DMA_FROM_DEVICE);
+				bdp->cbd_bufaddr = cpu_to_fec32(0);
 				dev_kfree_skb(skb);
 			}
 			bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 15/16] net: fec: call dma_unmap_single on mapped tx buffers at restart
@ 2016-04-06  2:26   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:26 UTC (permalink / raw)
  To: linux-arm-kernel

Make sure any pending tx buffers are unmapped when the
fec is restarted.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: no change
---
 drivers/net/ethernet/freescale/fec_main.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index a38acf2..101d820 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -404,6 +404,7 @@ dma_mapping_error:
 		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
 		dma_unmap_single(&fep->pdev->dev, fec32_to_cpu(bdp->cbd_bufaddr),
 				 fec16_to_cpu(bdp->cbd_datlen), DMA_TO_DEVICE);
+		bdp->cbd_bufaddr = cpu_to_fec32(0);
 	}
 	return ERR_PTR(-ENOMEM);
 }
@@ -761,11 +762,18 @@ static void reset_tx_queue(struct fec_enet_private *fep,
 	txq->bd.cur = bdp;
 	for (i = 0; i < txq->bd.ring_size; i++) {
 		/* Initialize the BD for every fragment in the page. */
+		if (bdp->cbd_bufaddr) {
+			if (!IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
+				dma_unmap_single(&fep->pdev->dev,
+						 fec32_to_cpu(bdp->cbd_bufaddr),
+						 fec16_to_cpu(bdp->cbd_datlen),
+						 DMA_TO_DEVICE);
+			bdp->cbd_bufaddr = cpu_to_fec32(0);
+		}
 		if (txq->tx_skbuff[i]) {
 			dev_kfree_skb_any(txq->tx_skbuff[i]);
 			txq->tx_skbuff[i] = NULL;
 		}
-		bdp->cbd_bufaddr = cpu_to_fec32(0);
 		bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
 					   BD_SC_WRAP : 0);
 		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
@@ -2643,6 +2651,7 @@ static void fec_enet_free_buffers(struct net_device *ndev)
 						 fec32_to_cpu(bdp->cbd_bufaddr),
 						 FEC_ENET_RX_FRSIZE - fep->rx_align,
 						 DMA_FROM_DEVICE);
+				bdp->cbd_bufaddr = cpu_to_fec32(0);
 				dev_kfree_skb(skb);
 			}
 			bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 16/16] net: fec: don't set cbd_bufaddr unless no mapping error
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  2:26   ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:26 UTC (permalink / raw)
  To: netdev, davem, fugang.duan, lznuaa
  Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky

Not assigning cbd_bufaddr on error will prevent trying to
unmap the error in case the FEC is reset.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: no change
---
 drivers/net/ethernet/freescale/fec_main.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 101d820..c2ed8be 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -600,7 +600,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
 	int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 	struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
 	void *bufaddr;
-	unsigned long dmabuf;
+	dma_addr_t dmabuf;
 	unsigned int estatus = 0;
 
 	bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
@@ -1295,17 +1295,21 @@ fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff
 {
 	struct  fec_enet_private *fep = netdev_priv(ndev);
 	int off;
+	dma_addr_t dmabuf;
 
 	off = ((unsigned long)skb->data) & fep->rx_align;
 	if (off)
 		skb_reserve(skb, fep->rx_align + 1 - off);
 
-	bdp->cbd_bufaddr = cpu_to_fec32(dma_map_single(&fep->pdev->dev, skb->data, FEC_ENET_RX_FRSIZE - fep->rx_align, DMA_FROM_DEVICE));
-	if (dma_mapping_error(&fep->pdev->dev, fec32_to_cpu(bdp->cbd_bufaddr))) {
+	dmabuf = dma_map_single(&fep->pdev->dev, skb->data,
+				FEC_ENET_RX_FRSIZE - fep->rx_align,
+				DMA_FROM_DEVICE);
+	if (dma_mapping_error(&fep->pdev->dev, dmabuf)) {
 		if (net_ratelimit())
 			netdev_err(ndev, "Rx DMA memory map failed\n");
 		return -ENOMEM;
 	}
+	bdp->cbd_bufaddr = cpu_to_fec32(dmabuf);
 
 	return 0;
 }
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 16/16] net: fec: don't set cbd_bufaddr unless no mapping error
@ 2016-04-06  2:26   ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06  2:26 UTC (permalink / raw)
  To: linux-arm-kernel

Not assigning cbd_bufaddr on error will prevent trying to
unmap the error in case the FEC is reset.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v3: no change
---
 drivers/net/ethernet/freescale/fec_main.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 101d820..c2ed8be 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -600,7 +600,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
 	int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 	struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
 	void *bufaddr;
-	unsigned long dmabuf;
+	dma_addr_t dmabuf;
 	unsigned int estatus = 0;
 
 	bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
@@ -1295,17 +1295,21 @@ fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff
 {
 	struct  fec_enet_private *fep = netdev_priv(ndev);
 	int off;
+	dma_addr_t dmabuf;
 
 	off = ((unsigned long)skb->data) & fep->rx_align;
 	if (off)
 		skb_reserve(skb, fep->rx_align + 1 - off);
 
-	bdp->cbd_bufaddr = cpu_to_fec32(dma_map_single(&fep->pdev->dev, skb->data, FEC_ENET_RX_FRSIZE - fep->rx_align, DMA_FROM_DEVICE));
-	if (dma_mapping_error(&fep->pdev->dev, fec32_to_cpu(bdp->cbd_bufaddr))) {
+	dmabuf = dma_map_single(&fep->pdev->dev, skb->data,
+				FEC_ENET_RX_FRSIZE - fep->rx_align,
+				DMA_FROM_DEVICE);
+	if (dma_mapping_error(&fep->pdev->dev, dmabuf)) {
 		if (net_ratelimit())
 			netdev_err(ndev, "Rx DMA memory map failed\n");
 		return -ENOMEM;
 	}
+	bdp->cbd_bufaddr = cpu_to_fec32(dmabuf);
 
 	return 0;
 }
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* RE: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06  8:51   ` Fugang Duan
  -1 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06  8:51 UTC (permalink / raw)
  To: Troy Kisky, netdev, davem, lznuaa
  Cc: Fabio Estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev@vger.kernel.org; davem@davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa@gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
> kernel@lists.infradead.org; johannes@sipsolutions.net;
> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
> arnd@arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
> 
> V3 has
> 
> 1 dropped patch "net: fec: print more debug info in fec_timeout"
> 2 new patches
> 0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
> 0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch
> 
> 1 combined patch
> 0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch
> 
> The changes are noted on individual patches
> 
> My measured performance of this series is
> 
> before patch set
> 365 Mbits/sec Tx/407 RX
> 
> after patch set
> 374 Tx/427 Rx
> 

I doubt the performance data,  I validate it on i.MX6q sabresd board on the latest commit(4da46cebbd3b) in net tree.
The test log as below:

root@imx6qdlsolo:~# uname -a
Linux imx6qdlsolo 4.6.0-rc1-00318-g4da46ce #180 SMP Wed Apr 6 16:24:09 CST 2016 armv7l GNU/Linux
root@imx6qdlsolo:~# cat /sys/devices/soc0/soc_id
i.MX6Q
root@imx6qdlsolo:~# echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
root@imx6qdlsolo:~# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
996000
root@imx6qdlsolo:~# iperf  -s &
[1] 891
root@imx6qdlsolo:~# ------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------

root@imx6qdlsolo:~# [  4] local 10.192.242.107 port 5001 connected with 10.192.242.248 port 38409
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0-20.0 sec  1.40 GBytes   602 Mbits/sec

root@imx6qdlsolo:~# iperf -c 10.192.242.248 -t 20
------------------------------------------------------------
Client connecting to 10.192.242.248, TCP port 5001
TCP window size: 43.8 KByte (default)
------------------------------------------------------------
[  3] local 10.192.242.107 port 52124 connected with 10.192.242.248 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-20.0 sec   776 MBytes   325 Mbits/sec


TCP RX performance is 602Mbps, TX is only 325Mbps,   TX path has some performance issue in net tree.
I will dig out it.


> 
> Troy Kisky (16):
>   net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
>   net: fec: remove unused interrupt FEC_ENET_TS_TIMER
>   net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
>   net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
>   net: fec: reduce interrupts
>   net: fec: split off napi routine with 3 queues
>   net: fec: don't clear all rx queue bits when just one is being checked
>   net: fec: set cbd_sc without relying on previous value
>   net: fec: eliminate calls to fec_enet_get_prevdesc
>   net: fec: move restart test for efficiency
>   net: fec: clear cbd_sc after transmission to help with debugging
>   net: fec: dump all tx queues in fec_dump
>   net: fec: detect tx int lost
>   net: fec: create subroutine reset_tx_queue
>   net: fec: call dma_unmap_single on mapped tx buffers at restart
>   net: fec: don't set cbd_bufaddr unless no mapping error
> 
>  drivers/net/ethernet/freescale/fec.h      |  10 +-
>  drivers/net/ethernet/freescale/fec_main.c | 410 ++++++++++++++++------------
> --
>  2 files changed, 218 insertions(+), 202 deletions(-)
> 
> --
> 2.5.0

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-06  8:51   ` Fugang Duan
  0 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa at gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
> kernel at lists.infradead.org; johannes at sipsolutions.net;
> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
> arnd at arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
> 
> V3 has
> 
> 1 dropped patch "net: fec: print more debug info in fec_timeout"
> 2 new patches
> 0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
> 0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch
> 
> 1 combined patch
> 0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch
> 
> The changes are noted on individual patches
> 
> My measured performance of this series is
> 
> before patch set
> 365 Mbits/sec Tx/407 RX
> 
> after patch set
> 374 Tx/427 Rx
> 

I doubt the performance data,  I validate it on i.MX6q sabresd board on the latest commit(4da46cebbd3b) in net tree.
The test log as below:

root at imx6qdlsolo:~# uname -a
Linux imx6qdlsolo 4.6.0-rc1-00318-g4da46ce #180 SMP Wed Apr 6 16:24:09 CST 2016 armv7l GNU/Linux
root at imx6qdlsolo:~# cat /sys/devices/soc0/soc_id
i.MX6Q
root at imx6qdlsolo:~# echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
root at imx6qdlsolo:~# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
996000
root at imx6qdlsolo:~# iperf  -s &
[1] 891
root at imx6qdlsolo:~# ------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------

root at imx6qdlsolo:~# [  4] local 10.192.242.107 port 5001 connected with 10.192.242.248 port 38409
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0-20.0 sec  1.40 GBytes   602 Mbits/sec

root at imx6qdlsolo:~# iperf -c 10.192.242.248 -t 20
------------------------------------------------------------
Client connecting to 10.192.242.248, TCP port 5001
TCP window size: 43.8 KByte (default)
------------------------------------------------------------
[  3] local 10.192.242.107 port 52124 connected with 10.192.242.248 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-20.0 sec   776 MBytes   325 Mbits/sec


TCP RX performance is 602Mbps, TX is only 325Mbps,   TX path has some performance issue in net tree.
I will dig out it.


> 
> Troy Kisky (16):
>   net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
>   net: fec: remove unused interrupt FEC_ENET_TS_TIMER
>   net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
>   net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
>   net: fec: reduce interrupts
>   net: fec: split off napi routine with 3 queues
>   net: fec: don't clear all rx queue bits when just one is being checked
>   net: fec: set cbd_sc without relying on previous value
>   net: fec: eliminate calls to fec_enet_get_prevdesc
>   net: fec: move restart test for efficiency
>   net: fec: clear cbd_sc after transmission to help with debugging
>   net: fec: dump all tx queues in fec_dump
>   net: fec: detect tx int lost
>   net: fec: create subroutine reset_tx_queue
>   net: fec: call dma_unmap_single on mapped tx buffers at restart
>   net: fec: don't set cbd_bufaddr unless no mapping error
> 
>  drivers/net/ethernet/freescale/fec.h      |  10 +-
>  drivers/net/ethernet/freescale/fec_main.c | 410 ++++++++++++++++------------
> --
>  2 files changed, 218 insertions(+), 202 deletions(-)
> 
> --
> 2.5.0

^ permalink raw reply	[flat|nested] 72+ messages in thread

* RE: [PATCH net-next V3 02/16] net: fec: remove unused interrupt FEC_ENET_TS_TIMER
  2016-04-06  2:25   ` Troy Kisky
@ 2016-04-06  9:10     ` Fugang Duan
  -1 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06  9:10 UTC (permalink / raw)
  To: Troy Kisky, netdev, davem, lznuaa
  Cc: andrew, stillcompiling, arnd, sergei.shtylyov, gerg,
	Fabio Estevam, johannes, l.stach, linux-arm-kernel, tremyfr

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev@vger.kernel.org; davem@davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa@gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
> kernel@lists.infradead.org; johannes@sipsolutions.net;
> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
> arnd@arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 02/16] net: fec: remove unused interrupt
> FEC_ENET_TS_TIMER
> 
> FEC_ENET_TS_TIMER is not checked in the interrupt routine so there is no need
> to enable it.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> 
> ---
> v3: New patch
> 
> Frank Li said "TS_TIMER should never be triggered."
> when discussing another patch.
> ---
>  drivers/net/ethernet/freescale/fec.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fec.h
> b/drivers/net/ethernet/freescale/fec.h
> index 195122e..6dd0ba8 100644
> --- a/drivers/net/ethernet/freescale/fec.h
> +++ b/drivers/net/ethernet/freescale/fec.h
> @@ -374,8 +374,8 @@ struct bufdesc_ex {
>  #define FEC_ENET_TS_AVAIL       ((uint)0x00010000)
>  #define FEC_ENET_TS_TIMER       ((uint)0x00008000)
> 
> -#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII
> | FEC_ENET_TS_TIMER)
> -#define FEC_NAPI_IMASK	(FEC_ENET_MII | FEC_ENET_TS_TIMER)
> +#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII)
> +#define FEC_NAPI_IMASK	FEC_ENET_MII
>  #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
> 
>  /* ENET interrupt coalescing macro define */
> --
> 2.5.0

Acked-by: Fugang Duan <fugang.duan@nxp.com>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 02/16] net: fec: remove unused interrupt FEC_ENET_TS_TIMER
@ 2016-04-06  9:10     ` Fugang Duan
  0 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa at gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
> kernel at lists.infradead.org; johannes at sipsolutions.net;
> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
> arnd at arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 02/16] net: fec: remove unused interrupt
> FEC_ENET_TS_TIMER
> 
> FEC_ENET_TS_TIMER is not checked in the interrupt routine so there is no need
> to enable it.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> 
> ---
> v3: New patch
> 
> Frank Li said "TS_TIMER should never be triggered."
> when discussing another patch.
> ---
>  drivers/net/ethernet/freescale/fec.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fec.h
> b/drivers/net/ethernet/freescale/fec.h
> index 195122e..6dd0ba8 100644
> --- a/drivers/net/ethernet/freescale/fec.h
> +++ b/drivers/net/ethernet/freescale/fec.h
> @@ -374,8 +374,8 @@ struct bufdesc_ex {
>  #define FEC_ENET_TS_AVAIL       ((uint)0x00010000)
>  #define FEC_ENET_TS_TIMER       ((uint)0x00008000)
> 
> -#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII
> | FEC_ENET_TS_TIMER)
> -#define FEC_NAPI_IMASK	(FEC_ENET_MII | FEC_ENET_TS_TIMER)
> +#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII)
> +#define FEC_NAPI_IMASK	FEC_ENET_MII
>  #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
> 
>  /* ENET interrupt coalescing macro define */
> --
> 2.5.0

Acked-by: Fugang Duan <fugang.duan@nxp.com>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* RE: [PATCH net-next V3 03/16] net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
  2016-04-06  2:25   ` Troy Kisky
@ 2016-04-06  9:12     ` Fugang Duan
  -1 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06  9:12 UTC (permalink / raw)
  To: Troy Kisky, netdev, davem, lznuaa
  Cc: Fabio Estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev@vger.kernel.org; davem@davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa@gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
> kernel@lists.infradead.org; johannes@sipsolutions.net;
> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
> arnd@arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 03/16] net: fec: return IRQ_HANDLED if
> fec_ptp_check_pps_event handled it
> 
> fec_ptp_check_pps_event will return 1 if FEC_T_TF_MASK caused an interrupt.
> Don't return IRQ_NONE in this case.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> 
> ---
> v3: New patch, came from feedback from another patch.
> ---
>  drivers/net/ethernet/freescale/fec_main.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index a011719..7993040 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -1579,8 +1579,8 @@ fec_enet_interrupt(int irq, void *dev_id)
>  	}
> 
>  	if (fep->ptp_clock)
> -		fec_ptp_check_pps_event(fep);
> -
> +		if (fec_ptp_check_pps_event(fep))
> +			ret = IRQ_HANDLED;
>  	return ret;
>  }
> 
> --
> 2.5.0

Acked-by: Fugang Duan <fugang.duan@nxp.com>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 03/16] net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
@ 2016-04-06  9:12     ` Fugang Duan
  0 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06  9:12 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa at gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
> kernel at lists.infradead.org; johannes at sipsolutions.net;
> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
> arnd at arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 03/16] net: fec: return IRQ_HANDLED if
> fec_ptp_check_pps_event handled it
> 
> fec_ptp_check_pps_event will return 1 if FEC_T_TF_MASK caused an interrupt.
> Don't return IRQ_NONE in this case.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> 
> ---
> v3: New patch, came from feedback from another patch.
> ---
>  drivers/net/ethernet/freescale/fec_main.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index a011719..7993040 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -1579,8 +1579,8 @@ fec_enet_interrupt(int irq, void *dev_id)
>  	}
> 
>  	if (fep->ptp_clock)
> -		fec_ptp_check_pps_event(fep);
> -
> +		if (fec_ptp_check_pps_event(fep))
> +			ret = IRQ_HANDLED;
>  	return ret;
>  }
> 
> --
> 2.5.0

Acked-by: Fugang Duan <fugang.duan@nxp.com>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* RE: [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on previous value
  2016-04-06  2:25   ` Troy Kisky
@ 2016-04-06  9:51     ` Fugang Duan
  -1 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06  9:51 UTC (permalink / raw)
  To: Troy Kisky, netdev, davem, lznuaa
  Cc: Fabio Estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev@vger.kernel.org; davem@davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa@gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
> kernel@lists.infradead.org; johannes@sipsolutions.net;
> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
> arnd@arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on
> previous value
> 
> Relying on the wrap bit of cdb_sc to stay valid once initialized when the
> controller also writes to this byte seems undesirable since we can easily know
> what the value should be.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> 
> ---
> v3: change commit message
> ---
>  drivers/net/ethernet/freescale/fec_main.c | 38 +++++++++----------------------
>  1 file changed, 11 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index 3cd0cdf..21d2cd0 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -340,9 +340,8 @@ fec_enet_txq_submit_frag_skb(struct
> fec_enet_priv_tx_q *txq,
>  		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
>  		ebdp = (struct bufdesc_ex *)bdp;
> 
> -		status = fec16_to_cpu(bdp->cbd_sc);
> -		status &= ~BD_ENET_TX_STATS;
> -		status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> +		status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> +				((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
>  		frag_len = skb_shinfo(skb)->frags[frag].size;
> 
>  		/* Handle the last BD specially */
> @@ -436,8 +435,6 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
>  	/* Fill in a Tx ring entry */
>  	bdp = txq->bd.cur;
>  	last_bdp = bdp;
> -	status = fec16_to_cpu(bdp->cbd_sc);
> -	status &= ~BD_ENET_TX_STATS;
> 
>  	/* Set buffer length and buffer pointer */
>  	bufaddr = skb->data;
> @@ -462,6 +459,8 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
>  		return NETDEV_TX_OK;
>  	}
> 
> +	status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> +			((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
>  	if (nr_frags) {
>  		last_bdp = fec_enet_txq_submit_frag_skb(txq, skb, ndev);
>  		if (IS_ERR(last_bdp)) {
> @@ -512,7 +511,6 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
>  	/* Send it on its way.  Tell FEC it's ready, interrupt when done,
>  	 * it's the last BD of the frame, and to put the CRC on the end.
>  	 */
> -	status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
>  	bdp->cbd_sc = cpu_to_fec16(status);
> 
>  	/* If this was the last BD in the ring, start at the beginning again. */ @@ -
> 544,11 +542,6 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq,
> struct sk_buff *skb,
>  	unsigned int estatus = 0;
>  	dma_addr_t addr;
> 
> -	status = fec16_to_cpu(bdp->cbd_sc);
> -	status &= ~BD_ENET_TX_STATS;
> -
> -	status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> -
>  	if (((unsigned long) data) & fep->tx_align ||
>  		fep->quirks & FEC_QUIRK_SWAP_FRAME) {
>  		memcpy(txq->tx_bounce[index], data, size); @@ -578,15
> +571,16 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq,
> struct sk_buff *skb,
>  		ebdp->cbd_esc = cpu_to_fec32(estatus);
>  	}
> 
> +	status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> +			((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
>  	/* Handle the last BD specially */
>  	if (last_tcp)
> -		status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
> +		status |= BD_ENET_TX_LAST;
>  	if (is_last) {
>  		status |= BD_ENET_TX_INTR;
>  		if (fep->bufdesc_ex)
>  			ebdp->cbd_esc |= cpu_to_fec32(BD_ENET_TX_INT);
>  	}
> -
>  	bdp->cbd_sc = cpu_to_fec16(status);
> 
>  	return 0;
> @@ -602,13 +596,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q
> *txq,
>  	struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
>  	void *bufaddr;
>  	unsigned long dmabuf;
> -	unsigned short status;
>  	unsigned int estatus = 0;
> 
> -	status = fec16_to_cpu(bdp->cbd_sc);
> -	status &= ~BD_ENET_TX_STATS;
> -	status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> -
>  	bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
>  	dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE;
>  	if (((unsigned long)bufaddr) & fep->tx_align || @@ -641,8 +630,8 @@
> fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
>  		ebdp->cbd_esc = cpu_to_fec32(estatus);
>  	}
> 
> -	bdp->cbd_sc = cpu_to_fec16(status);
> -
> +	bdp->cbd_sc = cpu_to_fec16(BD_ENET_TX_TC | BD_ENET_TX_READY |
> +			((bdp == txq->bd.last) ? BD_SC_WRAP : 0));
>  	return 0;
>  }
> 
> @@ -1454,12 +1443,6 @@ static int fec_rxq(struct net_device *ndev, struct
> fec_enet_priv_rx_q *rxq,
>  		}
> 
>  rx_processing_done:
> -		/* Clear the status flags for this buffer */
> -		status &= ~BD_ENET_RX_STATS;
> -
> -		/* Mark the buffer empty */
> -		status |= BD_ENET_RX_EMPTY;
> -
>  		if (fep->bufdesc_ex) {
>  			struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
> 
> @@ -1471,7 +1454,8 @@ rx_processing_done:
>  		 * performed before transferring ownership.
>  		 */
>  		wmb();
> -		bdp->cbd_sc = cpu_to_fec16(status);
> +		bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
> +				((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
> 
>  		/* Update BD pointer to next entry */
>  		bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
> --
> 2.5.0


Patch 08 ~ 16:  Acked-by: Fugang Duan <fugang.duan@nxp.com>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on previous value
@ 2016-04-06  9:51     ` Fugang Duan
  0 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa at gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
> kernel at lists.infradead.org; johannes at sipsolutions.net;
> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
> arnd at arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on
> previous value
> 
> Relying on the wrap bit of cdb_sc to stay valid once initialized when the
> controller also writes to this byte seems undesirable since we can easily know
> what the value should be.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> 
> ---
> v3: change commit message
> ---
>  drivers/net/ethernet/freescale/fec_main.c | 38 +++++++++----------------------
>  1 file changed, 11 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index 3cd0cdf..21d2cd0 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -340,9 +340,8 @@ fec_enet_txq_submit_frag_skb(struct
> fec_enet_priv_tx_q *txq,
>  		bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
>  		ebdp = (struct bufdesc_ex *)bdp;
> 
> -		status = fec16_to_cpu(bdp->cbd_sc);
> -		status &= ~BD_ENET_TX_STATS;
> -		status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> +		status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> +				((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
>  		frag_len = skb_shinfo(skb)->frags[frag].size;
> 
>  		/* Handle the last BD specially */
> @@ -436,8 +435,6 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
>  	/* Fill in a Tx ring entry */
>  	bdp = txq->bd.cur;
>  	last_bdp = bdp;
> -	status = fec16_to_cpu(bdp->cbd_sc);
> -	status &= ~BD_ENET_TX_STATS;
> 
>  	/* Set buffer length and buffer pointer */
>  	bufaddr = skb->data;
> @@ -462,6 +459,8 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
>  		return NETDEV_TX_OK;
>  	}
> 
> +	status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> +			((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
>  	if (nr_frags) {
>  		last_bdp = fec_enet_txq_submit_frag_skb(txq, skb, ndev);
>  		if (IS_ERR(last_bdp)) {
> @@ -512,7 +511,6 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
>  	/* Send it on its way.  Tell FEC it's ready, interrupt when done,
>  	 * it's the last BD of the frame, and to put the CRC on the end.
>  	 */
> -	status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
>  	bdp->cbd_sc = cpu_to_fec16(status);
> 
>  	/* If this was the last BD in the ring, start at the beginning again. */ @@ -
> 544,11 +542,6 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq,
> struct sk_buff *skb,
>  	unsigned int estatus = 0;
>  	dma_addr_t addr;
> 
> -	status = fec16_to_cpu(bdp->cbd_sc);
> -	status &= ~BD_ENET_TX_STATS;
> -
> -	status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> -
>  	if (((unsigned long) data) & fep->tx_align ||
>  		fep->quirks & FEC_QUIRK_SWAP_FRAME) {
>  		memcpy(txq->tx_bounce[index], data, size); @@ -578,15
> +571,16 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq,
> struct sk_buff *skb,
>  		ebdp->cbd_esc = cpu_to_fec32(estatus);
>  	}
> 
> +	status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> +			((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
>  	/* Handle the last BD specially */
>  	if (last_tcp)
> -		status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
> +		status |= BD_ENET_TX_LAST;
>  	if (is_last) {
>  		status |= BD_ENET_TX_INTR;
>  		if (fep->bufdesc_ex)
>  			ebdp->cbd_esc |= cpu_to_fec32(BD_ENET_TX_INT);
>  	}
> -
>  	bdp->cbd_sc = cpu_to_fec16(status);
> 
>  	return 0;
> @@ -602,13 +596,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q
> *txq,
>  	struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
>  	void *bufaddr;
>  	unsigned long dmabuf;
> -	unsigned short status;
>  	unsigned int estatus = 0;
> 
> -	status = fec16_to_cpu(bdp->cbd_sc);
> -	status &= ~BD_ENET_TX_STATS;
> -	status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> -
>  	bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
>  	dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE;
>  	if (((unsigned long)bufaddr) & fep->tx_align || @@ -641,8 +630,8 @@
> fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
>  		ebdp->cbd_esc = cpu_to_fec32(estatus);
>  	}
> 
> -	bdp->cbd_sc = cpu_to_fec16(status);
> -
> +	bdp->cbd_sc = cpu_to_fec16(BD_ENET_TX_TC | BD_ENET_TX_READY |
> +			((bdp == txq->bd.last) ? BD_SC_WRAP : 0));
>  	return 0;
>  }
> 
> @@ -1454,12 +1443,6 @@ static int fec_rxq(struct net_device *ndev, struct
> fec_enet_priv_rx_q *rxq,
>  		}
> 
>  rx_processing_done:
> -		/* Clear the status flags for this buffer */
> -		status &= ~BD_ENET_RX_STATS;
> -
> -		/* Mark the buffer empty */
> -		status |= BD_ENET_RX_EMPTY;
> -
>  		if (fep->bufdesc_ex) {
>  			struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
> 
> @@ -1471,7 +1454,8 @@ rx_processing_done:
>  		 * performed before transferring ownership.
>  		 */
>  		wmb();
> -		bdp->cbd_sc = cpu_to_fec16(status);
> +		bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
> +				((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
> 
>  		/* Update BD pointer to next entry */
>  		bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
> --
> 2.5.0


Patch 08 ~ 16:  Acked-by: Fugang Duan <fugang.duan@nxp.com>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* RE: [PATCH net-next V3 05/16] net: fec: reduce interrupts
  2016-04-06  2:25   ` Troy Kisky
@ 2016-04-06 10:06     ` Fugang Duan
  -1 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06 10:06 UTC (permalink / raw)
  To: Troy Kisky, netdev, davem, lznuaa
  Cc: andrew, stillcompiling, arnd, sergei.shtylyov, gerg,
	Fabio Estevam, johannes, l.stach, linux-arm-kernel, tremyfr

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev@vger.kernel.org; davem@davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa@gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
> kernel@lists.infradead.org; johannes@sipsolutions.net;
> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
> arnd@arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 05/16] net: fec: reduce interrupts
> 
> By clearing the NAPI interrupts in the NAPI routine and not in the interrupt
> handler, we can reduce the number of interrupts. We also don't need any status
> variables as the registers are still valid.
> 
> Also, notice that if budget pkts are received, the next call to fec_enet_rx_napi
> will now continue to receive the previously pending packets.
> 
> To test that this actually reduces interrupts, try this command before/after patch
> 
> cat /proc/interrupts |grep ether; \
> ping -s2800 192.168.0.201 -f -c1000 ; \
> cat /proc/interrupts |grep ether
> 
> For me, before this patch is 2996 interrupts.
> After patch is 2010 interrupts.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
>

As my previous comments on V2, if you want to improve performance, you can try to separate tx and rx napi process like calling netif_tx_napi_add() to initialize tx NAPI context.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 05/16] net: fec: reduce interrupts
@ 2016-04-06 10:06     ` Fugang Duan
  0 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-06 10:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
> <fugang.duan@nxp.com>; lznuaa at gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
> kernel at lists.infradead.org; johannes at sipsolutions.net;
> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
> arnd at arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> Subject: [PATCH net-next V3 05/16] net: fec: reduce interrupts
> 
> By clearing the NAPI interrupts in the NAPI routine and not in the interrupt
> handler, we can reduce the number of interrupts. We also don't need any status
> variables as the registers are still valid.
> 
> Also, notice that if budget pkts are received, the next call to fec_enet_rx_napi
> will now continue to receive the previously pending packets.
> 
> To test that this actually reduces interrupts, try this command before/after patch
> 
> cat /proc/interrupts |grep ether; \
> ping -s2800 192.168.0.201 -f -c1000 ; \
> cat /proc/interrupts |grep ether
> 
> For me, before this patch is 2996 interrupts.
> After patch is 2010 interrupts.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
>

As my previous comments on V2, if you want to improve performance, you can try to separate tx and rx napi process like calling netif_tx_napi_add() to initialize tx NAPI context.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-06  8:51   ` Fugang Duan
@ 2016-04-06 16:43     ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06 16:43 UTC (permalink / raw)
  To: Fugang Duan, netdev, davem, lznuaa
  Cc: Fabio Estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd

On 4/6/2016 1:51 AM, Fugang Duan wrote:
> From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
>> To: netdev@vger.kernel.org; davem@davemloft.net; Fugang Duan
>> <fugang.duan@nxp.com>; lznuaa@gmail.com
>> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
>> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
>> kernel@lists.infradead.org; johannes@sipsolutions.net;
>> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
>> arnd@arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
>> Subject: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
>>
>> V3 has
>>
>> 1 dropped patch "net: fec: print more debug info in fec_timeout"
>> 2 new patches
>> 0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
>> 0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch
>>
>> 1 combined patch
>> 0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch
>>
>> The changes are noted on individual patches
>>
>> My measured performance of this series is
>>
>> before patch set
>> 365 Mbits/sec Tx/407 RX
>>
>> after patch set
>> 374 Tx/427 Rx
>>
> 
> I doubt the performance data,  I validate it on i.MX6q sabresd board on the latest commit(4da46cebbd3b) in net tree.



I was doing UDP tests, as outlined in my V2 cover letter. Also, my cpu is 1G. Is yours 1.2G?




> root@imx6qdlsolo:~# uname -a
> Linux imx6qdlsolo 4.6.0-rc1-00318-g4da46ce #180 SMP Wed Apr 6 16:24:09 CST 2016 armv7l GNU/Linux


This is the V2 patch that I dropped.

I will force update my local net-next_master branch, to make testing this series easier.
Note that my local net-next_master branch has about 19 patches on top of this series.
so,

tkisky@office-server2:~/linux-imx6$ git reset --hard HEAD~19
HEAD is now at a125da7 net: fec: don't set cbd_bufaddr unless no mapping error


> 
> TCP RX performance is 602Mbps, TX is only 325Mbps,   TX path has some performance issue in net tree.
> I will dig out it.
> 
> 


More testing is always better. Thanks


>>
>> Troy Kisky (16):
>>   net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
>>   net: fec: remove unused interrupt FEC_ENET_TS_TIMER
>>   net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
>>   net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
>>   net: fec: reduce interrupts
>>   net: fec: split off napi routine with 3 queues
>>   net: fec: don't clear all rx queue bits when just one is being checked
>>   net: fec: set cbd_sc without relying on previous value
>>   net: fec: eliminate calls to fec_enet_get_prevdesc
>>   net: fec: move restart test for efficiency
>>   net: fec: clear cbd_sc after transmission to help with debugging
>>   net: fec: dump all tx queues in fec_dump
>>   net: fec: detect tx int lost
>>   net: fec: create subroutine reset_tx_queue
>>   net: fec: call dma_unmap_single on mapped tx buffers at restart
>>   net: fec: don't set cbd_bufaddr unless no mapping error
>>
>>  drivers/net/ethernet/freescale/fec.h      |  10 +-
>>  drivers/net/ethernet/freescale/fec_main.c | 410 ++++++++++++++++------------
>> --
>>  2 files changed, 218 insertions(+), 202 deletions(-)
>>
>> --
>> 2.5.0
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-06 16:43     ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/6/2016 1:51 AM, Fugang Duan wrote:
> From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
>> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
>> <fugang.duan@nxp.com>; lznuaa at gmail.com
>> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
>> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
>> kernel at lists.infradead.org; johannes at sipsolutions.net;
>> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
>> arnd at arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
>> Subject: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
>>
>> V3 has
>>
>> 1 dropped patch "net: fec: print more debug info in fec_timeout"
>> 2 new patches
>> 0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
>> 0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch
>>
>> 1 combined patch
>> 0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch
>>
>> The changes are noted on individual patches
>>
>> My measured performance of this series is
>>
>> before patch set
>> 365 Mbits/sec Tx/407 RX
>>
>> after patch set
>> 374 Tx/427 Rx
>>
> 
> I doubt the performance data,  I validate it on i.MX6q sabresd board on the latest commit(4da46cebbd3b) in net tree.



I was doing UDP tests, as outlined in my V2 cover letter. Also, my cpu is 1G. Is yours 1.2G?




> root at imx6qdlsolo:~# uname -a
> Linux imx6qdlsolo 4.6.0-rc1-00318-g4da46ce #180 SMP Wed Apr 6 16:24:09 CST 2016 armv7l GNU/Linux


This is the V2 patch that I dropped.

I will force update my local net-next_master branch, to make testing this series easier.
Note that my local net-next_master branch has about 19 patches on top of this series.
so,

tkisky at office-server2:~/linux-imx6$ git reset --hard HEAD~19
HEAD is now at a125da7 net: fec: don't set cbd_bufaddr unless no mapping error


> 
> TCP RX performance is 602Mbps, TX is only 325Mbps,   TX path has some performance issue in net tree.
> I will dig out it.
> 
> 


More testing is always better. Thanks


>>
>> Troy Kisky (16):
>>   net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
>>   net: fec: remove unused interrupt FEC_ENET_TS_TIMER
>>   net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
>>   net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
>>   net: fec: reduce interrupts
>>   net: fec: split off napi routine with 3 queues
>>   net: fec: don't clear all rx queue bits when just one is being checked
>>   net: fec: set cbd_sc without relying on previous value
>>   net: fec: eliminate calls to fec_enet_get_prevdesc
>>   net: fec: move restart test for efficiency
>>   net: fec: clear cbd_sc after transmission to help with debugging
>>   net: fec: dump all tx queues in fec_dump
>>   net: fec: detect tx int lost
>>   net: fec: create subroutine reset_tx_queue
>>   net: fec: call dma_unmap_single on mapped tx buffers at restart
>>   net: fec: don't set cbd_bufaddr unless no mapping error
>>
>>  drivers/net/ethernet/freescale/fec.h      |  10 +-
>>  drivers/net/ethernet/freescale/fec_main.c | 410 ++++++++++++++++------------
>> --
>>  2 files changed, 218 insertions(+), 202 deletions(-)
>>
>> --
>> 2.5.0
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-06 16:43     ` Troy Kisky
@ 2016-04-06 16:47       ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06 16:47 UTC (permalink / raw)
  To: Fugang Duan, netdev, davem, lznuaa
  Cc: Fabio Estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
	johannes, stillcompiling, sergei.shtylyov, arnd

On 4/6/2016 9:43 AM, Troy Kisky wrote:
> On 4/6/2016 1:51 AM, Fugang Duan wrote:
>> From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
>>> To: netdev@vger.kernel.org; davem@davemloft.net; Fugang Duan
>>> <fugang.duan@nxp.com>; lznuaa@gmail.com
>>> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
>>> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
>>> kernel@lists.infradead.org; johannes@sipsolutions.net;
>>> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
>>> arnd@arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
>>> Subject: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
>>>
>>> V3 has
>>>
>>> 1 dropped patch "net: fec: print more debug info in fec_timeout"
>>> 2 new patches
>>> 0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
>>> 0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch
>>>
>>> 1 combined patch
>>> 0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch
>>>
>>> The changes are noted on individual patches
>>>
>>> My measured performance of this series is
>>>
>>> before patch set
>>> 365 Mbits/sec Tx/407 RX
>>>
>>> after patch set
>>> 374 Tx/427 Rx
>>>
>>
>> I doubt the performance data,  I validate it on i.MX6q sabresd board on the latest commit(4da46cebbd3b) in net tree.
> 
> 
> 
> I was doing UDP tests, as outlined in my V2 cover letter. Also, my cpu is 1G. Is yours 1.2G?
> 
> 
> 
> 
>> root@imx6qdlsolo:~# uname -a
>> Linux imx6qdlsolo 4.6.0-rc1-00318-g4da46ce #180 SMP Wed Apr 6 16:24:09 CST 2016 armv7l GNU/Linux
> 
> 
> This is the V2 patch that I dropped.


Sorry, your right. It is the current head, without this series.


> 
> I will force update my local net-next_master branch, to make testing this series easier.
> Note that my local net-next_master branch has about 19 patches on top of this series.
> so,
> 
> tkisky@office-server2:~/linux-imx6$ git reset --hard HEAD~19
> HEAD is now at a125da7 net: fec: don't set cbd_bufaddr unless no mapping error
> 
> 
>>
>> TCP RX performance is 602Mbps, TX is only 325Mbps,   TX path has some performance issue in net tree.
>> I will dig out it.
>>
>>
> 
> 
> More testing is always better. Thanks
> 
> 
>>>
>>> Troy Kisky (16):
>>>   net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
>>>   net: fec: remove unused interrupt FEC_ENET_TS_TIMER
>>>   net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
>>>   net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
>>>   net: fec: reduce interrupts
>>>   net: fec: split off napi routine with 3 queues
>>>   net: fec: don't clear all rx queue bits when just one is being checked
>>>   net: fec: set cbd_sc without relying on previous value
>>>   net: fec: eliminate calls to fec_enet_get_prevdesc
>>>   net: fec: move restart test for efficiency
>>>   net: fec: clear cbd_sc after transmission to help with debugging
>>>   net: fec: dump all tx queues in fec_dump
>>>   net: fec: detect tx int lost
>>>   net: fec: create subroutine reset_tx_queue
>>>   net: fec: call dma_unmap_single on mapped tx buffers at restart
>>>   net: fec: don't set cbd_bufaddr unless no mapping error
>>>
>>>  drivers/net/ethernet/freescale/fec.h      |  10 +-
>>>  drivers/net/ethernet/freescale/fec_main.c | 410 ++++++++++++++++------------
>>> --
>>>  2 files changed, 218 insertions(+), 202 deletions(-)
>>>
>>> --
>>> 2.5.0
>>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-06 16:47       ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-06 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/6/2016 9:43 AM, Troy Kisky wrote:
> On 4/6/2016 1:51 AM, Fugang Duan wrote:
>> From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
>>> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
>>> <fugang.duan@nxp.com>; lznuaa at gmail.com
>>> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
>>> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
>>> kernel at lists.infradead.org; johannes at sipsolutions.net;
>>> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
>>> arnd at arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
>>> Subject: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
>>>
>>> V3 has
>>>
>>> 1 dropped patch "net: fec: print more debug info in fec_timeout"
>>> 2 new patches
>>> 0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
>>> 0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch
>>>
>>> 1 combined patch
>>> 0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch
>>>
>>> The changes are noted on individual patches
>>>
>>> My measured performance of this series is
>>>
>>> before patch set
>>> 365 Mbits/sec Tx/407 RX
>>>
>>> after patch set
>>> 374 Tx/427 Rx
>>>
>>
>> I doubt the performance data,  I validate it on i.MX6q sabresd board on the latest commit(4da46cebbd3b) in net tree.
> 
> 
> 
> I was doing UDP tests, as outlined in my V2 cover letter. Also, my cpu is 1G. Is yours 1.2G?
> 
> 
> 
> 
>> root at imx6qdlsolo:~# uname -a
>> Linux imx6qdlsolo 4.6.0-rc1-00318-g4da46ce #180 SMP Wed Apr 6 16:24:09 CST 2016 armv7l GNU/Linux
> 
> 
> This is the V2 patch that I dropped.


Sorry, your right. It is the current head, without this series.


> 
> I will force update my local net-next_master branch, to make testing this series easier.
> Note that my local net-next_master branch has about 19 patches on top of this series.
> so,
> 
> tkisky at office-server2:~/linux-imx6$ git reset --hard HEAD~19
> HEAD is now at a125da7 net: fec: don't set cbd_bufaddr unless no mapping error
> 
> 
>>
>> TCP RX performance is 602Mbps, TX is only 325Mbps,   TX path has some performance issue in net tree.
>> I will dig out it.
>>
>>
> 
> 
> More testing is always better. Thanks
> 
> 
>>>
>>> Troy Kisky (16):
>>>   net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
>>>   net: fec: remove unused interrupt FEC_ENET_TS_TIMER
>>>   net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
>>>   net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
>>>   net: fec: reduce interrupts
>>>   net: fec: split off napi routine with 3 queues
>>>   net: fec: don't clear all rx queue bits when just one is being checked
>>>   net: fec: set cbd_sc without relying on previous value
>>>   net: fec: eliminate calls to fec_enet_get_prevdesc
>>>   net: fec: move restart test for efficiency
>>>   net: fec: clear cbd_sc after transmission to help with debugging
>>>   net: fec: dump all tx queues in fec_dump
>>>   net: fec: detect tx int lost
>>>   net: fec: create subroutine reset_tx_queue
>>>   net: fec: call dma_unmap_single on mapped tx buffers at restart
>>>   net: fec: don't set cbd_bufaddr unless no mapping error
>>>
>>>  drivers/net/ethernet/freescale/fec.h      |  10 +-
>>>  drivers/net/ethernet/freescale/fec_main.c | 410 ++++++++++++++++------------
>>> --
>>>  2 files changed, 218 insertions(+), 202 deletions(-)
>>>
>>> --
>>> 2.5.0
>>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 05/16] net: fec: reduce interrupts
  2016-04-06  2:25   ` Troy Kisky
@ 2016-04-06 21:20     ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2016-04-06 21:20 UTC (permalink / raw)
  To: troy.kisky
  Cc: netdev, fugang.duan, lznuaa, fabio.estevam, l.stach, andrew,
	tremyfr, gerg, linux-arm-kernel, johannes, stillcompiling,
	sergei.shtylyov, arnd

From: Troy Kisky <troy.kisky@boundarydevices.com>
Date: Tue,  5 Apr 2016 19:25:51 -0700

> By clearing the NAPI interrupts in the NAPI routine
> and not in the interrupt handler, we can reduce the
> number of interrupts. We also don't need any status
> variables as the registers are still valid.
> 
> Also, notice that if budget pkts are received, the
> next call to fec_enet_rx_napi will now continue to
> receive the previously pending packets.
> 
> To test that this actually reduces interrupts, try
> this command before/after patch
> 
> cat /proc/interrupts |grep ether; \
> ping -s2800 192.168.0.201 -f -c1000 ; \
> cat /proc/interrupts |grep ether
> 
> For me, before this patch is 2996 interrupts.
> After patch is 2010 interrupts.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

I really don't think this is a good idea at all.

I would instead really rather see you stash away the
status register values into some piece of software state,
and then re-read them before you are about to finish a
NAPI poll cycle.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 05/16] net: fec: reduce interrupts
@ 2016-04-06 21:20     ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2016-04-06 21:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com>
Date: Tue,  5 Apr 2016 19:25:51 -0700

> By clearing the NAPI interrupts in the NAPI routine
> and not in the interrupt handler, we can reduce the
> number of interrupts. We also don't need any status
> variables as the registers are still valid.
> 
> Also, notice that if budget pkts are received, the
> next call to fec_enet_rx_napi will now continue to
> receive the previously pending packets.
> 
> To test that this actually reduces interrupts, try
> this command before/after patch
> 
> cat /proc/interrupts |grep ether; \
> ping -s2800 192.168.0.201 -f -c1000 ; \
> cat /proc/interrupts |grep ether
> 
> For me, before this patch is 2996 interrupts.
> After patch is 2010 interrupts.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

I really don't think this is a good idea at all.

I would instead really rather see you stash away the
status register values into some piece of software state,
and then re-read them before you are about to finish a
NAPI poll cycle.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-06 21:20   ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2016-04-06 21:20 UTC (permalink / raw)
  To: troy.kisky
  Cc: netdev, fugang.duan, lznuaa, fabio.estevam, l.stach, andrew,
	tremyfr, gerg, linux-arm-kernel, johannes, stillcompiling,
	sergei.shtylyov, arnd


This is a way too large patch series.

Please split it up into smaller, more logical, pieces.

Thanks.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-06 21:20   ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2016-04-06 21:20 UTC (permalink / raw)
  To: linux-arm-kernel


This is a way too large patch series.

Please split it up into smaller, more logical, pieces.

Thanks.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 05/16] net: fec: reduce interrupts
  2016-04-06 21:20     ` David Miller
@ 2016-04-07  0:42       ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-07  0:42 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, fugang.duan, lznuaa, fabio.estevam, l.stach, andrew,
	tremyfr, gerg, linux-arm-kernel, johannes, stillcompiling,
	sergei.shtylyov, arnd

On 4/6/2016 2:20 PM, David Miller wrote:
> From: Troy Kisky <troy.kisky@boundarydevices.com>
> Date: Tue,  5 Apr 2016 19:25:51 -0700
> 
>> By clearing the NAPI interrupts in the NAPI routine
>> and not in the interrupt handler, we can reduce the
>> number of interrupts. We also don't need any status
>> variables as the registers are still valid.
>>
>> Also, notice that if budget pkts are received, the
>> next call to fec_enet_rx_napi will now continue to
>> receive the previously pending packets.
>>
>> To test that this actually reduces interrupts, try
>> this command before/after patch
>>
>> cat /proc/interrupts |grep ether; \
>> ping -s2800 192.168.0.201 -f -c1000 ; \
>> cat /proc/interrupts |grep ether
>>
>> For me, before this patch is 2996 interrupts.
>> After patch is 2010 interrupts.
>>
>> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> 
> I really don't think this is a good idea at all.
> 
> I would instead really rather see you stash away the
> status register values into some piece of software state,
> and then re-read them before you are about to finish a
> NAPI poll cycle.
> 
> 

Sure, that's an easy change. But if a TX int is what caused the interrupt
and masks them, and then a RX packet happens before napi runs, do you want
the TX serviced 1st, or RX ?

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 05/16] net: fec: reduce interrupts
@ 2016-04-07  0:42       ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-07  0:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/6/2016 2:20 PM, David Miller wrote:
> From: Troy Kisky <troy.kisky@boundarydevices.com>
> Date: Tue,  5 Apr 2016 19:25:51 -0700
> 
>> By clearing the NAPI interrupts in the NAPI routine
>> and not in the interrupt handler, we can reduce the
>> number of interrupts. We also don't need any status
>> variables as the registers are still valid.
>>
>> Also, notice that if budget pkts are received, the
>> next call to fec_enet_rx_napi will now continue to
>> receive the previously pending packets.
>>
>> To test that this actually reduces interrupts, try
>> this command before/after patch
>>
>> cat /proc/interrupts |grep ether; \
>> ping -s2800 192.168.0.201 -f -c1000 ; \
>> cat /proc/interrupts |grep ether
>>
>> For me, before this patch is 2996 interrupts.
>> After patch is 2010 interrupts.
>>
>> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> 
> I really don't think this is a good idea at all.
> 
> I would instead really rather see you stash away the
> status register values into some piece of software state,
> and then re-read them before you are about to finish a
> NAPI poll cycle.
> 
> 

Sure, that's an easy change. But if a TX int is what caused the interrupt
and masks them, and then a RX packet happens before napi runs, do you want
the TX serviced 1st, or RX ?

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-06 21:20   ` David Miller
@ 2016-04-07  1:09     ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-07  1:09 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, fugang.duan, lznuaa, fabio.estevam, l.stach, andrew,
	tremyfr, gerg, linux-arm-kernel, johannes, stillcompiling,
	sergei.shtylyov, arnd

On 4/6/2016 2:20 PM, David Miller wrote:
> 
> This is a way too large patch series.
> 
> Please split it up into smaller, more logical, pieces.
> 
> Thanks.
> 

If you apply the 1st 3 that have been acked, I'll be at 13.

Would I then send the next 5 for  V4, and when that is applied
send another V4 with the next 8 that have been already been acked?

Thanks
Troy

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-07  1:09     ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-07  1:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/6/2016 2:20 PM, David Miller wrote:
> 
> This is a way too large patch series.
> 
> Please split it up into smaller, more logical, pieces.
> 
> Thanks.
> 

If you apply the 1st 3 that have been acked, I'll be at 13.

Would I then send the next 5 for  V4, and when that is applied
send another V4 with the next 8 that have been already been acked?

Thanks
Troy

^ permalink raw reply	[flat|nested] 72+ messages in thread

* RE: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-06 16:43     ` Troy Kisky
@ 2016-04-07  1:23       ` Fugang Duan
  -1 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-07  1:23 UTC (permalink / raw)
  To: Troy Kisky, netdev, davem, lznuaa
  Cc: andrew, stillcompiling, arnd, sergei.shtylyov, gerg,
	Fabio Estevam, johannes, l.stach, linux-arm-kernel, tremyfr

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Thursday, April 07, 2016 12:43 AM
> To: Fugang Duan <fugang.duan@nxp.com>; netdev@vger.kernel.org;
> davem@davemloft.net; lznuaa@gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
> kernel@lists.infradead.org; johannes@sipsolutions.net;
> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
> arnd@arndb.de
> Subject: Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
> 
> On 4/6/2016 1:51 AM, Fugang Duan wrote:
> > From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday,
> > April 06, 2016 10:26 AM
> >> To: netdev@vger.kernel.org; davem@davemloft.net; Fugang Duan
> >> <fugang.duan@nxp.com>; lznuaa@gmail.com
> >> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach@pengutronix.de;
> >> andrew@lunn.ch; tremyfr@gmail.com; gerg@uclinux.org; linux-arm-
> >> kernel@lists.infradead.org; johannes@sipsolutions.net;
> >> stillcompiling@gmail.com; sergei.shtylyov@cogentembedded.com;
> >> arnd@arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> >> Subject: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
> >>
> >> V3 has
> >>
> >> 1 dropped patch "net: fec: print more debug info in fec_timeout"
> >> 2 new patches
> >> 0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
> >> 0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch
> >>
> >> 1 combined patch
> >> 0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch
> >>
> >> The changes are noted on individual patches
> >>
> >> My measured performance of this series is
> >>
> >> before patch set
> >> 365 Mbits/sec Tx/407 RX
> >>
> >> after patch set
> >> 374 Tx/427 Rx
> >>
> >
> > I doubt the performance data,  I validate it on i.MX6q sabresd board on the
> latest commit(4da46cebbd3b) in net tree.
> 
> 
> 
> I was doing UDP tests, as outlined in my V2 cover letter. Also, my cpu is 1G. Is
> yours 1.2G?
> 
It is also 1GHz.

I will double test UDP performance.

> 
> 
> 
> > root@imx6qdlsolo:~# uname -a
> > Linux imx6qdlsolo 4.6.0-rc1-00318-g4da46ce #180 SMP Wed Apr 6 16:24:09
> > CST 2016 armv7l GNU/Linux
> 
> 
> This is the V2 patch that I dropped.
> 
> I will force update my local net-next_master branch, to make testing this series
> easier.
> Note that my local net-next_master branch has about 19 patches on top of this
> series.
> so,
> 
> tkisky@office-server2:~/linux-imx6$ git reset --hard HEAD~19 HEAD is now at
> a125da7 net: fec: don't set cbd_bufaddr unless no mapping error
> 
I see.

> 
> >
> > TCP RX performance is 602Mbps, TX is only 325Mbps,   TX path has some
> performance issue in net tree.
> > I will dig out it.
> >
> >
> 
> 
> More testing is always better. Thanks
> 
> 
> >>
> >> Troy Kisky (16):
> >>   net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
> >>   net: fec: remove unused interrupt FEC_ENET_TS_TIMER
> >>   net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
> >>   net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
> >>   net: fec: reduce interrupts
> >>   net: fec: split off napi routine with 3 queues
> >>   net: fec: don't clear all rx queue bits when just one is being checked
> >>   net: fec: set cbd_sc without relying on previous value
> >>   net: fec: eliminate calls to fec_enet_get_prevdesc
> >>   net: fec: move restart test for efficiency
> >>   net: fec: clear cbd_sc after transmission to help with debugging
> >>   net: fec: dump all tx queues in fec_dump
> >>   net: fec: detect tx int lost
> >>   net: fec: create subroutine reset_tx_queue
> >>   net: fec: call dma_unmap_single on mapped tx buffers at restart
> >>   net: fec: don't set cbd_bufaddr unless no mapping error
> >>
> >>  drivers/net/ethernet/freescale/fec.h      |  10 +-
> >>  drivers/net/ethernet/freescale/fec_main.c | 410
> >> ++++++++++++++++------------
> >> --
> >>  2 files changed, 218 insertions(+), 202 deletions(-)
> >>
> >> --
> >> 2.5.0
> >

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-07  1:23       ` Fugang Duan
  0 siblings, 0 replies; 72+ messages in thread
From: Fugang Duan @ 2016-04-07  1:23 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Thursday, April 07, 2016 12:43 AM
> To: Fugang Duan <fugang.duan@nxp.com>; netdev at vger.kernel.org;
> davem at davemloft.net; lznuaa at gmail.com
> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
> kernel at lists.infradead.org; johannes at sipsolutions.net;
> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
> arnd at arndb.de
> Subject: Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
> 
> On 4/6/2016 1:51 AM, Fugang Duan wrote:
> > From: Troy Kisky <troy.kisky@boundarydevices.com> Sent: Wednesday,
> > April 06, 2016 10:26 AM
> >> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
> >> <fugang.duan@nxp.com>; lznuaa at gmail.com
> >> Cc: Fabio Estevam <fabio.estevam@nxp.com>; l.stach at pengutronix.de;
> >> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
> >> kernel at lists.infradead.org; johannes at sipsolutions.net;
> >> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
> >> arnd at arndb.de; Troy Kisky <troy.kisky@boundarydevices.com>
> >> Subject: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
> >>
> >> V3 has
> >>
> >> 1 dropped patch "net: fec: print more debug info in fec_timeout"
> >> 2 new patches
> >> 0002-net-fec-remove-unused-interrupt-FEC_ENET_TS_TIMER.patch
> >> 0003-net-fec-return-IRQ_HANDLED-if-fec_ptp_check_pps_even.patch
> >>
> >> 1 combined patch
> >> 0004-net-fec-pass-rxq-txq-to-fec_enet_rx-tx_queue-instead.patch
> >>
> >> The changes are noted on individual patches
> >>
> >> My measured performance of this series is
> >>
> >> before patch set
> >> 365 Mbits/sec Tx/407 RX
> >>
> >> after patch set
> >> 374 Tx/427 Rx
> >>
> >
> > I doubt the performance data,  I validate it on i.MX6q sabresd board on the
> latest commit(4da46cebbd3b) in net tree.
> 
> 
> 
> I was doing UDP tests, as outlined in my V2 cover letter. Also, my cpu is 1G. Is
> yours 1.2G?
> 
It is also 1GHz.

I will double test UDP performance.

> 
> 
> 
> > root at imx6qdlsolo:~# uname -a
> > Linux imx6qdlsolo 4.6.0-rc1-00318-g4da46ce #180 SMP Wed Apr 6 16:24:09
> > CST 2016 armv7l GNU/Linux
> 
> 
> This is the V2 patch that I dropped.
> 
> I will force update my local net-next_master branch, to make testing this series
> easier.
> Note that my local net-next_master branch has about 19 patches on top of this
> series.
> so,
> 
> tkisky at office-server2:~/linux-imx6$ git reset --hard HEAD~19 HEAD is now at
> a125da7 net: fec: don't set cbd_bufaddr unless no mapping error
> 
I see.

> 
> >
> > TCP RX performance is 602Mbps, TX is only 325Mbps,   TX path has some
> performance issue in net tree.
> > I will dig out it.
> >
> >
> 
> 
> More testing is always better. Thanks
> 
> 
> >>
> >> Troy Kisky (16):
> >>   net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set
> >>   net: fec: remove unused interrupt FEC_ENET_TS_TIMER
> >>   net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it
> >>   net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
> >>   net: fec: reduce interrupts
> >>   net: fec: split off napi routine with 3 queues
> >>   net: fec: don't clear all rx queue bits when just one is being checked
> >>   net: fec: set cbd_sc without relying on previous value
> >>   net: fec: eliminate calls to fec_enet_get_prevdesc
> >>   net: fec: move restart test for efficiency
> >>   net: fec: clear cbd_sc after transmission to help with debugging
> >>   net: fec: dump all tx queues in fec_dump
> >>   net: fec: detect tx int lost
> >>   net: fec: create subroutine reset_tx_queue
> >>   net: fec: call dma_unmap_single on mapped tx buffers at restart
> >>   net: fec: don't set cbd_bufaddr unless no mapping error
> >>
> >>  drivers/net/ethernet/freescale/fec.h      |  10 +-
> >>  drivers/net/ethernet/freescale/fec_main.c | 410
> >> ++++++++++++++++------------
> >> --
> >>  2 files changed, 218 insertions(+), 202 deletions(-)
> >>
> >> --
> >> 2.5.0
> >

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 05/16] net: fec: reduce interrupts
  2016-04-07  0:42       ` Troy Kisky
@ 2016-04-07  3:57         ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2016-04-07  3:57 UTC (permalink / raw)
  To: troy.kisky
  Cc: netdev, fugang.duan, lznuaa, fabio.estevam, l.stach, andrew,
	tremyfr, gerg, linux-arm-kernel, johannes, stillcompiling,
	sergei.shtylyov, arnd

From: Troy Kisky <troy.kisky@boundarydevices.com>
Date: Wed, 6 Apr 2016 17:42:47 -0700

> Sure, that's an easy change. But if a TX int is what caused the
> interrupt and masks them, and then a RX packet happens before napi
> runs, do you want the TX serviced 1st, or RX ?

If you properly split your driver up into seperate interrupt/poll
instances, one for TX one for RX, you wouldn't need to ask me
that question now would you?

:-)

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 05/16] net: fec: reduce interrupts
@ 2016-04-07  3:57         ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2016-04-07  3:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com>
Date: Wed, 6 Apr 2016 17:42:47 -0700

> Sure, that's an easy change. But if a TX int is what caused the
> interrupt and masks them, and then a RX packet happens before napi
> runs, do you want the TX serviced 1st, or RX ?

If you properly split your driver up into seperate interrupt/poll
instances, one for TX one for RX, you wouldn't need to ask me
that question now would you?

:-)

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-07  1:09     ` Troy Kisky
@ 2016-04-07  3:58       ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2016-04-07  3:58 UTC (permalink / raw)
  To: troy.kisky
  Cc: netdev, fugang.duan, lznuaa, fabio.estevam, l.stach, andrew,
	tremyfr, gerg, linux-arm-kernel, johannes, stillcompiling,
	sergei.shtylyov, arnd

From: Troy Kisky <troy.kisky@boundarydevices.com>
Date: Wed, 6 Apr 2016 18:09:17 -0700

> On 4/6/2016 2:20 PM, David Miller wrote:
>> 
>> This is a way too large patch series.
>> 
>> Please split it up into smaller, more logical, pieces.
>> 
>> Thanks.
>> 
> 
> If you apply the 1st 3 that have been acked, I'll be at 13.
> 
> Would I then send the next 5 for  V4, and when that is applied
> send another V4 with the next 8 that have been already been acked?

What other reasonable option is there?  I can't think of any.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-07  3:58       ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2016-04-07  3:58 UTC (permalink / raw)
  To: linux-arm-kernel

From: Troy Kisky <troy.kisky@boundarydevices.com>
Date: Wed, 6 Apr 2016 18:09:17 -0700

> On 4/6/2016 2:20 PM, David Miller wrote:
>> 
>> This is a way too large patch series.
>> 
>> Please split it up into smaller, more logical, pieces.
>> 
>> Thanks.
>> 
> 
> If you apply the 1st 3 that have been acked, I'll be at 13.
> 
> Would I then send the next 5 for  V4, and when that is applied
> send another V4 with the next 8 that have been already been acked?

What other reasonable option is there?  I can't think of any.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-07  3:58       ` David Miller
@ 2016-04-07 15:35         ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-07 15:35 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, fugang.duan, lznuaa, fabio.estevam, l.stach, andrew,
	tremyfr, gerg, linux-arm-kernel, johannes, stillcompiling,
	sergei.shtylyov, arnd

On 4/6/2016 8:58 PM, David Miller wrote:
> From: Troy Kisky <troy.kisky@boundarydevices.com>
> Date: Wed, 6 Apr 2016 18:09:17 -0700
> 
>> On 4/6/2016 2:20 PM, David Miller wrote:
>>>
>>> This is a way too large patch series.
>>>
>>> Please split it up into smaller, more logical, pieces.
>>>
>>> Thanks.
>>>
>>
>> If you apply the 1st 3 that have been acked, I'll be at 13.
>>
>> Would I then send the next 5 for  V4, and when that is applied
>> send another V4 with the next 8 that have been already been acked?
> 
> What other reasonable option is there?  I can't think of any.
> 

A V1 for the next 8 would not be too unreasonable.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-07 15:35         ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-07 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/6/2016 8:58 PM, David Miller wrote:
> From: Troy Kisky <troy.kisky@boundarydevices.com>
> Date: Wed, 6 Apr 2016 18:09:17 -0700
> 
>> On 4/6/2016 2:20 PM, David Miller wrote:
>>>
>>> This is a way too large patch series.
>>>
>>> Please split it up into smaller, more logical, pieces.
>>>
>>> Thanks.
>>>
>>
>> If you apply the 1st 3 that have been acked, I'll be at 13.
>>
>> Would I then send the next 5 for  V4, and when that is applied
>> send another V4 with the next 8 that have been already been acked?
> 
> What other reasonable option is there?  I can't think of any.
> 

A V1 for the next 8 would not be too unreasonable.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 05/16] net: fec: reduce interrupts
  2016-04-07  3:57         ` David Miller
@ 2016-04-07 15:50           ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-07 15:50 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, fugang.duan, lznuaa, fabio.estevam, l.stach, andrew,
	tremyfr, gerg, linux-arm-kernel, johannes, stillcompiling,
	sergei.shtylyov, arnd

On 4/6/2016 8:57 PM, David Miller wrote:
> From: Troy Kisky <troy.kisky@boundarydevices.com>
> Date: Wed, 6 Apr 2016 17:42:47 -0700
> 
>> Sure, that's an easy change. But if a TX int is what caused the
>> interrupt and masks them, and then a RX packet happens before napi
>> runs, do you want the TX serviced 1st, or RX ?
> 
> If you properly split your driver up into seperate interrupt/poll
> instances, one for TX one for RX, you wouldn't need to ask me
> that question now would you?
> 
> :-)
> 

I absolutely claim no ownership :-)

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 05/16] net: fec: reduce interrupts
@ 2016-04-07 15:50           ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-07 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/6/2016 8:57 PM, David Miller wrote:
> From: Troy Kisky <troy.kisky@boundarydevices.com>
> Date: Wed, 6 Apr 2016 17:42:47 -0700
> 
>> Sure, that's an easy change. But if a TX int is what caused the
>> interrupt and masks them, and then a RX packet happens before napi
>> runs, do you want the TX serviced 1st, or RX ?
> 
> If you properly split your driver up into seperate interrupt/poll
> instances, one for TX one for RX, you wouldn't need to ask me
> that question now would you?
> 
> :-)
> 

I absolutely claim no ownership :-)

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-06  2:25 ` Troy Kisky
@ 2016-04-14 10:13   ` Holger Schurig
  -1 siblings, 0 replies; 72+ messages in thread
From: Holger Schurig @ 2016-04-14 10:13 UTC (permalink / raw)
  To: Troy Kisky
  Cc: netdev, davem, fugang.duan, lznuaa, andrew, stillcompiling, arnd,
	sergei.shtylyov, gerg, fabio.estevam, johannes, l.stach,
	linux-arm-kernel, tremyfr

Do you guys that work with the FEC driver ever run with
CONFIG_DMA_API_DEBUG enabled?

I ask this Because I get this error when it's turned on when I do some
"rsync" transfer to my device:

[   58.420980] ------------[ cut here ]------------
[   58.425667] WARNING: CPU: 0 PID: 377 at /home/schurig/d/mkarm/linux-4.5/lib/dma-debug.c:1096 check_unmap+0x9d0/0xab8()
[   58.436405] fec 2188000.ethernet: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x0000000000000000] [size=66 bytes]
[   58.450248] Modules linked in: bnep usbhid imx_sdma flexcan btusb btrtl btbcm btintel smsc95xx usbnet mii bluetooth
[   58.460882] CPU: 0 PID: 377 Comm: sshd Tainted: G        W       4.5.1 #3
[   58.467671] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[   58.474199] Backtrace: 
[   58.476675] [<c0012a24>] (dump_backtrace) from [<c0012c20>] (show_stack+0x18/0x1c)
[   58.484244]  r6:60000113 r5:c05a96c0 r4:00000000 r3:00000000
[   58.489964] [<c0012c08>] (show_stack) from [<c01dbc4c>] (dump_stack+0x9c/0xb0)
[   58.497197] [<c01dbbb0>] (dump_stack) from [<c001f558>] (warn_slowpath_common+0x8c/0xbc)
[   58.505286]  r6:c01f9c74 r5:00000009 r4:ee9f17f8 r3:c0596da4
[   58.511002] [<c001f4cc>] (warn_slowpath_common) from [<c001f5c0>] (warn_slowpath_fmt+0x38/0x40)
[   58.519698]  r8:00000042 r7:00000001 r6:00000000 r5:00000000 r4:c050c020
[   58.526470] [<c001f58c>] (warn_slowpath_fmt) from [<c01f9c74>] (check_unmap+0x9d0/0xab8)
[   58.534559]  r3:c0520e6c r2:c050c020
[   58.538159]  r4:00000000
[   58.540710] [<c01f92a4>] (check_unmap) from [<c01f9de0>] (debug_dma_unmap_page+0x84/0x8c)
[   58.548886]  r10:ef2ec000 r9:f09e5fa0 r8:ef0ef810 r7:00000001 r6:00000000 r5:00000042
[   58.556780]  r4:00000001
[   58.559336] [<c01f9d5c>] (debug_dma_unmap_page) from [<c02cdf00>] (fec_txq+0x140/0x31c)
[   58.567338]  r8:ef0ef810 r7:00000000 r6:00000000 r5:00000000 r4:ef2c6000
[   58.574108] [<c02cddc0>] (fec_txq) from [<c02ce2f4>] (fec_enet_napi_q1+0x98/0xe8)
[   58.581589]  r10:08000000 r9:ef2ec580 r8:00000000 r7:00000040 r6:00000000 r5:ef2ec000
[   58.589483]  r4:0c008000
[   58.592042] [<c02ce25c>] (fec_enet_napi_q1) from [<c038b3d8>] (net_rx_action+0x1fc/0x2f0)
[   58.600218]  r10:ee9f19c0 r9:00000040 r8:c059e100 r7:0000012c r6:ffffa1a3 r5:c02ce25c
[   58.608112]  r4:ef2ec580 r3:ee9f19c0
[   58.611720] [<c038b1dc>] (net_rx_action) from [<c00224c4>] (__do_softirq+0x134/0x254)
[   58.619549]  r10:c059e080 r9:40000003 r8:00000100 r7:ee9f0000 r6:c059e08c r5:00000003
[   58.627445]  r4:00000000
[   58.629995] [<c0022390>] (__do_softirq) from [<c00228a8>] (irq_exit+0xb8/0x120)
[   58.637303]  r10:ee9f1e38 r9:f4001100 r8:ef008000 r7:00000001 r6:00000000 r5:00000000
[   58.645197]  r4:c05970b8
[   58.647754] [<c00227f0>] (irq_exit) from [<c0061340>] (__handle_domain_irq+0x68/0xbc)
[   58.655583]  r4:c05970b8 r3:c0064e24
[   58.659190] [<c00612d8>] (__handle_domain_irq) from [<c00093f8>] (gic_handle_irq+0x50/0x90)
[   58.667539]  r8:f4000100 r7:ee9f1ac8 r6:f400010c r5:c059e7a0 r4:c05a9788 r3:ee9f1ac8
[   58.675350] [<c00093a8>] (gic_handle_irq) from [<c0013740>] (__irq_svc+0x40/0x54)
[   58.682833] Exception stack(0xee9f1ac8 to 0xee9f1b10)
[   58.687887] 1ac0:                   00000000 ee9c0d4c 0000000c 00000000 00000000 00000000
[   58.696067] 1ae0: ee9f1e38 ee9f1e3c ee9f1e40 edc6ac00 ee9f1e38 ee9f1e1c 00000000 ee9f1b18
[   58.704245] 1b00: ee9c0d4c c00df648 60000013 ffffffff
[   58.709295]  r9:edc6ac00 r8:ee9f1e40 r7:ee9f1afc r6:ffffffff r5:60000013 r4:c00df648
[   58.717112] [<c00df544>] (do_select) from [<c00dfcb8>] (core_sys_select+0x144/0x320)
[   58.724854]  r10:ee9f1e38 r9:ee9f1e38 r8:0000000c r7:805af838 r6:00000000 r5:805af848
[   58.732749]  r4:00000004
[   58.735300] [<c00dfb74>] (core_sys_select) from [<c00dff68>] (SyS_select+0xd4/0x120)
[   58.743042]  r10:00000000 r9:0000000c r8:805af848 r7:805af838 r6:00000000 r5:ee9f1f70
[   58.750936]  r4:00000000
[   58.753488] [<c00dfe94>] (SyS_select) from [<c000f820>] (ret_fast_syscall+0x0/0x34)
[   58.761143]  r9:ee9f0000 r8:c000f9c4 r7:0000008e r6:00000000 r5:7f5f77c0 r4:00000000
[   58.768984] ---[ end trace cb88537fdc8fa202 ]---

The amount of data transferred isn't even huge:

sent 382,979 bytes  received 28,086 bytes  32,885.20 bytes/sec
total size is 147,758,955  speedup is 359.45



This happens with:

* Kernel 4.5
* Kernel 4.5.1
* Kernel 4.5.1 with the fec-related patches from 4.6-rc3
* Kernel 4.5.1 with the fec-related patches from 4.6-rc3 and Troy's
  patch series from this thread


Should I post an extra e-mail with "BUG" in the subject?

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-14 10:13   ` Holger Schurig
  0 siblings, 0 replies; 72+ messages in thread
From: Holger Schurig @ 2016-04-14 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

Do you guys that work with the FEC driver ever run with
CONFIG_DMA_API_DEBUG enabled?

I ask this Because I get this error when it's turned on when I do some
"rsync" transfer to my device:

[   58.420980] ------------[ cut here ]------------
[   58.425667] WARNING: CPU: 0 PID: 377 at /home/schurig/d/mkarm/linux-4.5/lib/dma-debug.c:1096 check_unmap+0x9d0/0xab8()
[   58.436405] fec 2188000.ethernet: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x0000000000000000] [size=66 bytes]
[   58.450248] Modules linked in: bnep usbhid imx_sdma flexcan btusb btrtl btbcm btintel smsc95xx usbnet mii bluetooth
[   58.460882] CPU: 0 PID: 377 Comm: sshd Tainted: G        W       4.5.1 #3
[   58.467671] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[   58.474199] Backtrace: 
[   58.476675] [<c0012a24>] (dump_backtrace) from [<c0012c20>] (show_stack+0x18/0x1c)
[   58.484244]  r6:60000113 r5:c05a96c0 r4:00000000 r3:00000000
[   58.489964] [<c0012c08>] (show_stack) from [<c01dbc4c>] (dump_stack+0x9c/0xb0)
[   58.497197] [<c01dbbb0>] (dump_stack) from [<c001f558>] (warn_slowpath_common+0x8c/0xbc)
[   58.505286]  r6:c01f9c74 r5:00000009 r4:ee9f17f8 r3:c0596da4
[   58.511002] [<c001f4cc>] (warn_slowpath_common) from [<c001f5c0>] (warn_slowpath_fmt+0x38/0x40)
[   58.519698]  r8:00000042 r7:00000001 r6:00000000 r5:00000000 r4:c050c020
[   58.526470] [<c001f58c>] (warn_slowpath_fmt) from [<c01f9c74>] (check_unmap+0x9d0/0xab8)
[   58.534559]  r3:c0520e6c r2:c050c020
[   58.538159]  r4:00000000
[   58.540710] [<c01f92a4>] (check_unmap) from [<c01f9de0>] (debug_dma_unmap_page+0x84/0x8c)
[   58.548886]  r10:ef2ec000 r9:f09e5fa0 r8:ef0ef810 r7:00000001 r6:00000000 r5:00000042
[   58.556780]  r4:00000001
[   58.559336] [<c01f9d5c>] (debug_dma_unmap_page) from [<c02cdf00>] (fec_txq+0x140/0x31c)
[   58.567338]  r8:ef0ef810 r7:00000000 r6:00000000 r5:00000000 r4:ef2c6000
[   58.574108] [<c02cddc0>] (fec_txq) from [<c02ce2f4>] (fec_enet_napi_q1+0x98/0xe8)
[   58.581589]  r10:08000000 r9:ef2ec580 r8:00000000 r7:00000040 r6:00000000 r5:ef2ec000
[   58.589483]  r4:0c008000
[   58.592042] [<c02ce25c>] (fec_enet_napi_q1) from [<c038b3d8>] (net_rx_action+0x1fc/0x2f0)
[   58.600218]  r10:ee9f19c0 r9:00000040 r8:c059e100 r7:0000012c r6:ffffa1a3 r5:c02ce25c
[   58.608112]  r4:ef2ec580 r3:ee9f19c0
[   58.611720] [<c038b1dc>] (net_rx_action) from [<c00224c4>] (__do_softirq+0x134/0x254)
[   58.619549]  r10:c059e080 r9:40000003 r8:00000100 r7:ee9f0000 r6:c059e08c r5:00000003
[   58.627445]  r4:00000000
[   58.629995] [<c0022390>] (__do_softirq) from [<c00228a8>] (irq_exit+0xb8/0x120)
[   58.637303]  r10:ee9f1e38 r9:f4001100 r8:ef008000 r7:00000001 r6:00000000 r5:00000000
[   58.645197]  r4:c05970b8
[   58.647754] [<c00227f0>] (irq_exit) from [<c0061340>] (__handle_domain_irq+0x68/0xbc)
[   58.655583]  r4:c05970b8 r3:c0064e24
[   58.659190] [<c00612d8>] (__handle_domain_irq) from [<c00093f8>] (gic_handle_irq+0x50/0x90)
[   58.667539]  r8:f4000100 r7:ee9f1ac8 r6:f400010c r5:c059e7a0 r4:c05a9788 r3:ee9f1ac8
[   58.675350] [<c00093a8>] (gic_handle_irq) from [<c0013740>] (__irq_svc+0x40/0x54)
[   58.682833] Exception stack(0xee9f1ac8 to 0xee9f1b10)
[   58.687887] 1ac0:                   00000000 ee9c0d4c 0000000c 00000000 00000000 00000000
[   58.696067] 1ae0: ee9f1e38 ee9f1e3c ee9f1e40 edc6ac00 ee9f1e38 ee9f1e1c 00000000 ee9f1b18
[   58.704245] 1b00: ee9c0d4c c00df648 60000013 ffffffff
[   58.709295]  r9:edc6ac00 r8:ee9f1e40 r7:ee9f1afc r6:ffffffff r5:60000013 r4:c00df648
[   58.717112] [<c00df544>] (do_select) from [<c00dfcb8>] (core_sys_select+0x144/0x320)
[   58.724854]  r10:ee9f1e38 r9:ee9f1e38 r8:0000000c r7:805af838 r6:00000000 r5:805af848
[   58.732749]  r4:00000004
[   58.735300] [<c00dfb74>] (core_sys_select) from [<c00dff68>] (SyS_select+0xd4/0x120)
[   58.743042]  r10:00000000 r9:0000000c r8:805af848 r7:805af838 r6:00000000 r5:ee9f1f70
[   58.750936]  r4:00000000
[   58.753488] [<c00dfe94>] (SyS_select) from [<c000f820>] (ret_fast_syscall+0x0/0x34)
[   58.761143]  r9:ee9f0000 r8:c000f9c4 r7:0000008e r6:00000000 r5:7f5f77c0 r4:00000000
[   58.768984] ---[ end trace cb88537fdc8fa202 ]---

The amount of data transferred isn't even huge:

sent 382,979 bytes  received 28,086 bytes  32,885.20 bytes/sec
total size is 147,758,955  speedup is 359.45



This happens with:

* Kernel 4.5
* Kernel 4.5.1
* Kernel 4.5.1 with the fec-related patches from 4.6-rc3
* Kernel 4.5.1 with the fec-related patches from 4.6-rc3 and Troy's
  patch series from this thread


Should I post an extra e-mail with "BUG" in the subject?

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-14 10:13   ` Holger Schurig
@ 2016-04-14 15:39     ` Troy Kisky
  -1 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-14 15:39 UTC (permalink / raw)
  To: Holger Schurig
  Cc: netdev, davem, fugang.duan, lznuaa, andrew, stillcompiling, arnd,
	sergei.shtylyov, gerg, fabio.estevam, johannes, l.stach,
	linux-arm-kernel, tremyfr

On 4/14/2016 3:13 AM, Holger Schurig wrote:
> Do you guys that work with the FEC driver ever run with
> CONFIG_DMA_API_DEBUG enabled?
> 
> I ask this Because I get this error when it's turned on when I do some
> "rsync" transfer to my device:
> 
> [   58.420980] ------------[ cut here ]------------
> [   58.425667] WARNING: CPU: 0 PID: 377 at /home/schurig/d/mkarm/linux-4.5/lib/dma-debug.c:1096 check_unmap+0x9d0/0xab8()
> [   58.436405] fec 2188000.ethernet: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x0000000000000000] [size=66 bytes]
> [   58.450248] Modules linked in: bnep usbhid imx_sdma flexcan btusb btrtl btbcm btintel smsc95xx usbnet mii bluetooth
> [   58.460882] CPU: 0 PID: 377 Comm: sshd Tainted: G        W       4.5.1 #3
> [   58.467671] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> [   58.474199] Backtrace: 
> [   58.476675] [<c0012a24>] (dump_backtrace) from [<c0012c20>] (show_stack+0x18/0x1c)
> [   58.484244]  r6:60000113 r5:c05a96c0 r4:00000000 r3:00000000
> [   58.489964] [<c0012c08>] (show_stack) from [<c01dbc4c>] (dump_stack+0x9c/0xb0)
> [   58.497197] [<c01dbbb0>] (dump_stack) from [<c001f558>] (warn_slowpath_common+0x8c/0xbc)
> [   58.505286]  r6:c01f9c74 r5:00000009 r4:ee9f17f8 r3:c0596da4
> [   58.511002] [<c001f4cc>] (warn_slowpath_common) from [<c001f5c0>] (warn_slowpath_fmt+0x38/0x40)
> [   58.519698]  r8:00000042 r7:00000001 r6:00000000 r5:00000000 r4:c050c020
> [   58.526470] [<c001f58c>] (warn_slowpath_fmt) from [<c01f9c74>] (check_unmap+0x9d0/0xab8)
> [   58.534559]  r3:c0520e6c r2:c050c020
> [   58.538159]  r4:00000000
> [   58.540710] [<c01f92a4>] (check_unmap) from [<c01f9de0>] (debug_dma_unmap_page+0x84/0x8c)
> [   58.548886]  r10:ef2ec000 r9:f09e5fa0 r8:ef0ef810 r7:00000001 r6:00000000 r5:00000042
> [   58.556780]  r4:00000001
> [   58.559336] [<c01f9d5c>] (debug_dma_unmap_page) from [<c02cdf00>] (fec_txq+0x140/0x31c)
> [   58.567338]  r8:ef0ef810 r7:00000000 r6:00000000 r5:00000000 r4:ef2c6000
> [   58.574108] [<c02cddc0>] (fec_txq) from [<c02ce2f4>] (fec_enet_napi_q1+0x98/0xe8)
> [   58.581589]  r10:08000000 r9:ef2ec580 r8:00000000 r7:00000040 r6:00000000 r5:ef2ec000


I think I've already fixed this, but I've only submitted once.

commit 466cb4a2e5583d2e18470f30d5948edcf4b947f5
Author: Troy Kisky <troy.kisky@boundarydevices.com>
Date:   Wed Jan 20 12:52:10 2016 -0700

    net: fec: update dirty_tx even if no skb

    If dirty_tx isn't updated, then dma_unmap_single
    will be called twice.

    Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 452be9c..150a90a 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1243,10 +1243,8 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
                                         fec16_to_cpu(bdp->cbd_datlen),
                                         DMA_TO_DEVICE);
                bdp->cbd_bufaddr = cpu_to_fec32(0);
-               if (!skb) {
-                       bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
-                       continue;
-               }
+               if (!skb)
+                       goto skb_done;

                /* Check for errors. */
                if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
@@ -1285,7 +1283,7 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)

                /* Free the sk buffer associated with this last transmit */
                dev_kfree_skb_any(skb);
-
+skb_done:
                /* Make sure the update to bdp and tx_skbuff are performed
                 * before dirty_tx
                 */

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-14 15:39     ` Troy Kisky
  0 siblings, 0 replies; 72+ messages in thread
From: Troy Kisky @ 2016-04-14 15:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/14/2016 3:13 AM, Holger Schurig wrote:
> Do you guys that work with the FEC driver ever run with
> CONFIG_DMA_API_DEBUG enabled?
> 
> I ask this Because I get this error when it's turned on when I do some
> "rsync" transfer to my device:
> 
> [   58.420980] ------------[ cut here ]------------
> [   58.425667] WARNING: CPU: 0 PID: 377 at /home/schurig/d/mkarm/linux-4.5/lib/dma-debug.c:1096 check_unmap+0x9d0/0xab8()
> [   58.436405] fec 2188000.ethernet: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x0000000000000000] [size=66 bytes]
> [   58.450248] Modules linked in: bnep usbhid imx_sdma flexcan btusb btrtl btbcm btintel smsc95xx usbnet mii bluetooth
> [   58.460882] CPU: 0 PID: 377 Comm: sshd Tainted: G        W       4.5.1 #3
> [   58.467671] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> [   58.474199] Backtrace: 
> [   58.476675] [<c0012a24>] (dump_backtrace) from [<c0012c20>] (show_stack+0x18/0x1c)
> [   58.484244]  r6:60000113 r5:c05a96c0 r4:00000000 r3:00000000
> [   58.489964] [<c0012c08>] (show_stack) from [<c01dbc4c>] (dump_stack+0x9c/0xb0)
> [   58.497197] [<c01dbbb0>] (dump_stack) from [<c001f558>] (warn_slowpath_common+0x8c/0xbc)
> [   58.505286]  r6:c01f9c74 r5:00000009 r4:ee9f17f8 r3:c0596da4
> [   58.511002] [<c001f4cc>] (warn_slowpath_common) from [<c001f5c0>] (warn_slowpath_fmt+0x38/0x40)
> [   58.519698]  r8:00000042 r7:00000001 r6:00000000 r5:00000000 r4:c050c020
> [   58.526470] [<c001f58c>] (warn_slowpath_fmt) from [<c01f9c74>] (check_unmap+0x9d0/0xab8)
> [   58.534559]  r3:c0520e6c r2:c050c020
> [   58.538159]  r4:00000000
> [   58.540710] [<c01f92a4>] (check_unmap) from [<c01f9de0>] (debug_dma_unmap_page+0x84/0x8c)
> [   58.548886]  r10:ef2ec000 r9:f09e5fa0 r8:ef0ef810 r7:00000001 r6:00000000 r5:00000042
> [   58.556780]  r4:00000001
> [   58.559336] [<c01f9d5c>] (debug_dma_unmap_page) from [<c02cdf00>] (fec_txq+0x140/0x31c)
> [   58.567338]  r8:ef0ef810 r7:00000000 r6:00000000 r5:00000000 r4:ef2c6000
> [   58.574108] [<c02cddc0>] (fec_txq) from [<c02ce2f4>] (fec_enet_napi_q1+0x98/0xe8)
> [   58.581589]  r10:08000000 r9:ef2ec580 r8:00000000 r7:00000040 r6:00000000 r5:ef2ec000


I think I've already fixed this, but I've only submitted once.

commit 466cb4a2e5583d2e18470f30d5948edcf4b947f5
Author: Troy Kisky <troy.kisky@boundarydevices.com>
Date:   Wed Jan 20 12:52:10 2016 -0700

    net: fec: update dirty_tx even if no skb

    If dirty_tx isn't updated, then dma_unmap_single
    will be called twice.

    Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 452be9c..150a90a 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1243,10 +1243,8 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
                                         fec16_to_cpu(bdp->cbd_datlen),
                                         DMA_TO_DEVICE);
                bdp->cbd_bufaddr = cpu_to_fec32(0);
-               if (!skb) {
-                       bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
-                       continue;
-               }
+               if (!skb)
+                       goto skb_done;

                /* Check for errors. */
                if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
@@ -1285,7 +1283,7 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)

                /* Free the sk buffer associated with this last transmit */
                dev_kfree_skb_any(skb);
-
+skb_done:
                /* Make sure the update to bdp and tx_skbuff are performed
                 * before dirty_tx
                 */

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH net-next V3 00/16] net: fec: cleanup and fixes
  2016-04-14 15:39     ` Troy Kisky
@ 2016-04-15  8:33       ` Holger Schurig
  -1 siblings, 0 replies; 72+ messages in thread
From: Holger Schurig @ 2016-04-15  8:33 UTC (permalink / raw)
  To: Troy Kisky
  Cc: netdev, davem, fugang.duan, lznuaa, andrew, stillcompiling, arnd,
	sergei.shtylyov, gerg, fabio.estevam, johannes, l.stach,
	linux-arm-kernel, tremyfr

> I think I've already fixed this, but I've only submitted once.
>
> commit 466cb4a2e5583d2e18470f30d5948edcf4b947f5
> Author: Troy Kisky <troy.kisky@boundarydevices.com>
> Date:   Wed Jan 20 12:52:10 2016 -0700
>
>     net: fec: update dirty_tx even if no skb
>
>     If dirty_tx isn't updated, then dma_unmap_single
>     will be called twice.
>
>     Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

Thanks!   This fixed the issue.  Have a

Tested-by: <holgerschurig@gmail.com>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH net-next V3 00/16] net: fec: cleanup and fixes
@ 2016-04-15  8:33       ` Holger Schurig
  0 siblings, 0 replies; 72+ messages in thread
From: Holger Schurig @ 2016-04-15  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

> I think I've already fixed this, but I've only submitted once.
>
> commit 466cb4a2e5583d2e18470f30d5948edcf4b947f5
> Author: Troy Kisky <troy.kisky@boundarydevices.com>
> Date:   Wed Jan 20 12:52:10 2016 -0700
>
>     net: fec: update dirty_tx even if no skb
>
>     If dirty_tx isn't updated, then dma_unmap_single
>     will be called twice.
>
>     Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

Thanks!   This fixed the issue.  Have a

Tested-by: <holgerschurig@gmail.com>

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2016-04-15  8:33 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-06  2:25 [PATCH net-next V3 00/16] net: fec: cleanup and fixes Troy Kisky
2016-04-06  2:25 ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 01/16] net: fec: only check queue 0 if RXF_0/TXF_0 interrupt is set Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 02/16] net: fec: remove unused interrupt FEC_ENET_TS_TIMER Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  9:10   ` Fugang Duan
2016-04-06  9:10     ` Fugang Duan
2016-04-06  2:25 ` [PATCH net-next V3 03/16] net: fec: return IRQ_HANDLED if fec_ptp_check_pps_event handled it Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  9:12   ` Fugang Duan
2016-04-06  9:12     ` Fugang Duan
2016-04-06  2:25 ` [PATCH net-next V3 04/16] net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 05/16] net: fec: reduce interrupts Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06 10:06   ` Fugang Duan
2016-04-06 10:06     ` Fugang Duan
2016-04-06 21:20   ` David Miller
2016-04-06 21:20     ` David Miller
2016-04-07  0:42     ` Troy Kisky
2016-04-07  0:42       ` Troy Kisky
2016-04-07  3:57       ` David Miller
2016-04-07  3:57         ` David Miller
2016-04-07 15:50         ` Troy Kisky
2016-04-07 15:50           ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 06/16] net: fec: split off napi routine with 3 queues Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 07/16] net: fec: don't clear all rx queue bits when just one is being checked Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on previous value Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  9:51   ` Fugang Duan
2016-04-06  9:51     ` Fugang Duan
2016-04-06  2:25 ` [PATCH net-next V3 09/16] net: fec: eliminate calls to fec_enet_get_prevdesc Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 10/16] net: fec: move restart test for efficiency Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 11/16] net: fec: clear cbd_sc after transmission to help with debugging Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 12/16] net: fec: dump all tx queues in fec_dump Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:25 ` [PATCH net-next V3 13/16] net: fec: detect tx int lost Troy Kisky
2016-04-06  2:25   ` Troy Kisky
2016-04-06  2:26 ` [PATCH net-next V3 14/16] net: fec: create subroutine reset_tx_queue Troy Kisky
2016-04-06  2:26   ` Troy Kisky
2016-04-06  2:26 ` [PATCH net-next V3 15/16] net: fec: call dma_unmap_single on mapped tx buffers at restart Troy Kisky
2016-04-06  2:26   ` Troy Kisky
2016-04-06  2:26 ` [PATCH net-next V3 16/16] net: fec: don't set cbd_bufaddr unless no mapping error Troy Kisky
2016-04-06  2:26   ` Troy Kisky
2016-04-06  8:51 ` [PATCH net-next V3 00/16] net: fec: cleanup and fixes Fugang Duan
2016-04-06  8:51   ` Fugang Duan
2016-04-06 16:43   ` Troy Kisky
2016-04-06 16:43     ` Troy Kisky
2016-04-06 16:47     ` Troy Kisky
2016-04-06 16:47       ` Troy Kisky
2016-04-07  1:23     ` Fugang Duan
2016-04-07  1:23       ` Fugang Duan
2016-04-06 21:20 ` David Miller
2016-04-06 21:20   ` David Miller
2016-04-07  1:09   ` Troy Kisky
2016-04-07  1:09     ` Troy Kisky
2016-04-07  3:58     ` David Miller
2016-04-07  3:58       ` David Miller
2016-04-07 15:35       ` Troy Kisky
2016-04-07 15:35         ` Troy Kisky
2016-04-14 10:13 ` Holger Schurig
2016-04-14 10:13   ` Holger Schurig
2016-04-14 15:39   ` Troy Kisky
2016-04-14 15:39     ` Troy Kisky
2016-04-15  8:33     ` Holger Schurig
2016-04-15  8:33       ` Holger Schurig

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.