All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues
@ 2017-03-15 11:04 Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config " Joao Pinto
                   ` (11 more replies)
  0 siblings, 12 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

As agreed with David Miller, this patch-set is the second of 3 to enable
multiple queues in stmmac.

This second one concentrates on dma operations adding functionalities as:
a) DMA Operation Mode configuration per channel and done in the multiple
queues configuration function
b) DMA IRQ enable and Disable by channel
c) DMA start and stop by channel
d) RX and TX ring length configuration by channel
e) RX and TX set tail pointer by channel
f) DMA Channel initialization broke into Channel comon, RX and TX
initialization
g) TSO being configured for all available channels
h) DMA interrupt treatment by channel

Joao Pinto (11):
  net: stmmac: prepare dma op mode config for multiple queues
  net: stmmac: enable/disable dma irq prepared for multiple queues
  net: stmmac: rx/tx dma start/stop prepared for multiple queues
  net: stmmac: prepare stmmac_tx_err for multiple queues
  net: stmmac: prepare dma interrupt treatment for multiple queues
  net: stmmac: rx watchdog config prepared for multiple queues
  net: stmmac: rx and tx ring length prepared for multiple queues
  net: stmmac: prepare rx/tx set tail function for multiple queues
  net: stmmac: dma channel init prepared for multiple queues
  net: stmmac: tso init prepared for multiple queues
  net: stmmac: stmmac interrupt treatment prepared for multiple queues

 drivers/net/ethernet/stmicro/stmmac/common.h       |  31 +-
 .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c    |   3 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c   | 192 ++++++-----
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h   |  20 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c   |  56 ++--
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h    |  15 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c    |  14 +-
 .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 367 ++++++++++++++++-----
 9 files changed, 465 insertions(+), 236 deletions(-)

-- 
2.9.3

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

* [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-05-08  6:56   ` Jan Kiszka
  2017-03-15 11:04 ` [PATCH v3 net-next 02/11] net: stmmac: enable/disable dma irq prepared " Joao Pinto
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares DMA Operation Mode configuration for multiple queues.
The work consisted on breaking the DMA operation Mode configuration function
into RX and TX scope and adapting its mechanism in stmmac_main.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/common.h      |   3 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c  | 118 +++++++++++-----------
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  82 +++++++++++----
 3 files changed, 124 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 9f0d26d..13bd3d4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -424,6 +424,9 @@ struct stmmac_dma_ops {
 	 * An invalid value enables the store-and-forward mode */
 	void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode,
 			 int rxfifosz);
+	void (*dma_rx_mode)(void __iomem *ioaddr, int mode, u32 channel,
+			    int fifosz);
+	void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel);
 	/* To track extra statistic (if supported) */
 	void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
 				   void __iomem *ioaddr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 6ac6b26..6285e8a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -182,70 +182,26 @@ static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt)
 		writel(riwt, ioaddr + DMA_CHAN_RX_WATCHDOG(i));
 }
 
-static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
-				    int rxmode, u32 channel, int rxfifosz)
+static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode,
+				       u32 channel, int fifosz)
 {
-	unsigned int rqs = rxfifosz / 256 - 1;
-	u32 mtl_tx_op, mtl_rx_op, mtl_rx_int;
-
-	/* Following code only done for channel 0, other channels not yet
-	 * supported.
-	 */
-	mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));
-
-	if (txmode == SF_DMA_MODE) {
-		pr_debug("GMAC: enable TX store and forward mode\n");
-		/* Transmit COE type 2 cannot be done in cut-through mode. */
-		mtl_tx_op |= MTL_OP_MODE_TSF;
-	} else {
-		pr_debug("GMAC: disabling TX SF (threshold %d)\n", txmode);
-		mtl_tx_op &= ~MTL_OP_MODE_TSF;
-		mtl_tx_op &= MTL_OP_MODE_TTC_MASK;
-		/* Set the transmit threshold */
-		if (txmode <= 32)
-			mtl_tx_op |= MTL_OP_MODE_TTC_32;
-		else if (txmode <= 64)
-			mtl_tx_op |= MTL_OP_MODE_TTC_64;
-		else if (txmode <= 96)
-			mtl_tx_op |= MTL_OP_MODE_TTC_96;
-		else if (txmode <= 128)
-			mtl_tx_op |= MTL_OP_MODE_TTC_128;
-		else if (txmode <= 192)
-			mtl_tx_op |= MTL_OP_MODE_TTC_192;
-		else if (txmode <= 256)
-			mtl_tx_op |= MTL_OP_MODE_TTC_256;
-		else if (txmode <= 384)
-			mtl_tx_op |= MTL_OP_MODE_TTC_384;
-		else
-			mtl_tx_op |= MTL_OP_MODE_TTC_512;
-	}
-	/* For an IP with DWC_EQOS_NUM_TXQ == 1, the fields TXQEN and TQS are RO
-	 * with reset values: TXQEN on, TQS == DWC_EQOS_TXFIFO_SIZE.
-	 * For an IP with DWC_EQOS_NUM_TXQ > 1, the fields TXQEN and TQS are R/W
-	 * with reset values: TXQEN off, TQS 256 bytes.
-	 *
-	 * Write the bits in both cases, since it will have no effect when RO.
-	 * For DWC_EQOS_NUM_TXQ > 1, the top bits in MTL_OP_MODE_TQS_MASK might
-	 * be RO, however, writing the whole TQS field will result in a value
-	 * equal to DWC_EQOS_TXFIFO_SIZE, just like for DWC_EQOS_NUM_TXQ == 1.
-	 */
-	mtl_tx_op |= MTL_OP_MODE_TXQEN | MTL_OP_MODE_TQS_MASK;
-	writel(mtl_tx_op, ioaddr +  MTL_CHAN_TX_OP_MODE(channel));
+	unsigned int rqs = fifosz / 256 - 1;
+	u32 mtl_rx_op, mtl_rx_int;
 
 	mtl_rx_op = readl(ioaddr + MTL_CHAN_RX_OP_MODE(channel));
 
-	if (rxmode == SF_DMA_MODE) {
+	if (mode == SF_DMA_MODE) {
 		pr_debug("GMAC: enable RX store and forward mode\n");
 		mtl_rx_op |= MTL_OP_MODE_RSF;
 	} else {
-		pr_debug("GMAC: disable RX SF mode (threshold %d)\n", rxmode);
+		pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
 		mtl_rx_op &= ~MTL_OP_MODE_RSF;
 		mtl_rx_op &= MTL_OP_MODE_RTC_MASK;
-		if (rxmode <= 32)
+		if (mode <= 32)
 			mtl_rx_op |= MTL_OP_MODE_RTC_32;
-		else if (rxmode <= 64)
+		else if (mode <= 64)
 			mtl_rx_op |= MTL_OP_MODE_RTC_64;
-		else if (rxmode <= 96)
+		else if (mode <= 96)
 			mtl_rx_op |= MTL_OP_MODE_RTC_96;
 		else
 			mtl_rx_op |= MTL_OP_MODE_RTC_128;
@@ -255,7 +211,7 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
 	mtl_rx_op |= rqs << MTL_OP_MODE_RQS_SHIFT;
 
 	/* enable flow control only if each channel gets 4 KiB or more FIFO */
-	if (rxfifosz >= 4096) {
+	if (fifosz >= 4096) {
 		unsigned int rfd, rfa;
 
 		mtl_rx_op |= MTL_OP_MODE_EHFC;
@@ -266,7 +222,7 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
 		 * Set Threshold for Deactivating Flow Control to min 1 frame,
 		 * i.e. 1500 bytes.
 		 */
-		switch (rxfifosz) {
+		switch (fifosz) {
 		case 4096:
 			/* This violates the above formula because of FIFO size
 			 * limit therefore overflow may occur in spite of this.
@@ -306,11 +262,49 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
 	       ioaddr + MTL_CHAN_INT_CTRL(channel));
 }
 
-static void dwmac4_dma_operation_mode(void __iomem *ioaddr, int txmode,
-				      int rxmode, int rxfifosz)
+static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode,
+				       u32 channel)
 {
-	/* Only Channel 0 is actually configured and used */
-	dwmac4_dma_chan_op_mode(ioaddr, txmode, rxmode, 0, rxfifosz);
+	u32 mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));
+
+	if (mode == SF_DMA_MODE) {
+		pr_debug("GMAC: enable TX store and forward mode\n");
+		/* Transmit COE type 2 cannot be done in cut-through mode. */
+		mtl_tx_op |= MTL_OP_MODE_TSF;
+	} else {
+		pr_debug("GMAC: disabling TX SF (threshold %d)\n", mode);
+		mtl_tx_op &= ~MTL_OP_MODE_TSF;
+		mtl_tx_op &= MTL_OP_MODE_TTC_MASK;
+		/* Set the transmit threshold */
+		if (mode <= 32)
+			mtl_tx_op |= MTL_OP_MODE_TTC_32;
+		else if (mode <= 64)
+			mtl_tx_op |= MTL_OP_MODE_TTC_64;
+		else if (mode <= 96)
+			mtl_tx_op |= MTL_OP_MODE_TTC_96;
+		else if (mode <= 128)
+			mtl_tx_op |= MTL_OP_MODE_TTC_128;
+		else if (mode <= 192)
+			mtl_tx_op |= MTL_OP_MODE_TTC_192;
+		else if (mode <= 256)
+			mtl_tx_op |= MTL_OP_MODE_TTC_256;
+		else if (mode <= 384)
+			mtl_tx_op |= MTL_OP_MODE_TTC_384;
+		else
+			mtl_tx_op |= MTL_OP_MODE_TTC_512;
+	}
+	/* For an IP with DWC_EQOS_NUM_TXQ == 1, the fields TXQEN and TQS are RO
+	 * with reset values: TXQEN on, TQS == DWC_EQOS_TXFIFO_SIZE.
+	 * For an IP with DWC_EQOS_NUM_TXQ > 1, the fields TXQEN and TQS are R/W
+	 * with reset values: TXQEN off, TQS 256 bytes.
+	 *
+	 * Write the bits in both cases, since it will have no effect when RO.
+	 * For DWC_EQOS_NUM_TXQ > 1, the top bits in MTL_OP_MODE_TQS_MASK might
+	 * be RO, however, writing the whole TQS field will result in a value
+	 * equal to DWC_EQOS_TXFIFO_SIZE, just like for DWC_EQOS_NUM_TXQ == 1.
+	 */
+	mtl_tx_op |= MTL_OP_MODE_TXQEN | MTL_OP_MODE_TQS_MASK;
+	writel(mtl_tx_op, ioaddr +  MTL_CHAN_TX_OP_MODE(channel));
 }
 
 static void dwmac4_get_hw_feature(void __iomem *ioaddr,
@@ -387,7 +381,8 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
 	.init = dwmac4_dma_init,
 	.axi = dwmac4_dma_axi,
 	.dump_regs = dwmac4_dump_dma_regs,
-	.dma_mode = dwmac4_dma_operation_mode,
+	.dma_rx_mode = dwmac4_dma_rx_chan_op_mode,
+	.dma_tx_mode = dwmac4_dma_tx_chan_op_mode,
 	.enable_dma_irq = dwmac4_enable_dma_irq,
 	.disable_dma_irq = dwmac4_disable_dma_irq,
 	.start_tx = dwmac4_dma_start_tx,
@@ -409,7 +404,8 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
 	.init = dwmac4_dma_init,
 	.axi = dwmac4_dma_axi,
 	.dump_regs = dwmac4_dump_dma_regs,
-	.dma_mode = dwmac4_dma_operation_mode,
+	.dma_rx_mode = dwmac4_dma_rx_chan_op_mode,
+	.dma_tx_mode = dwmac4_dma_tx_chan_op_mode,
 	.enable_dma_irq = dwmac410_enable_dma_irq,
 	.disable_dma_irq = dwmac4_disable_dma_irq,
 	.start_tx = dwmac4_dma_start_tx,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ec363e1..c4e4a53 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1285,14 +1285,20 @@ static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
  */
 static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
 {
+	u32 rx_channels_count = priv->plat->rx_queues_to_use;
+	u32 tx_channels_count = priv->plat->tx_queues_to_use;
 	int rxfifosz = priv->plat->rx_fifo_size;
+	u32 txmode = 0;
+	u32 rxmode = 0;
+	u32 chan = 0;
 
 	if (rxfifosz == 0)
 		rxfifosz = priv->dma_cap.rx_fifo_size;
 
-	if (priv->plat->force_thresh_dma_mode)
-		priv->hw->dma->dma_mode(priv->ioaddr, tc, tc, rxfifosz);
-	else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) {
+	if (priv->plat->force_thresh_dma_mode) {
+		txmode = tc;
+		rxmode = tc;
+	} else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) {
 		/*
 		 * In case of GMAC, SF mode can be enabled
 		 * to perform the TX COE in HW. This depends on:
@@ -1300,12 +1306,26 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
 		 * 2) There is no bugged Jumbo frame support
 		 *    that needs to not insert csum in the TDES.
 		 */
-		priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE,
-					rxfifosz);
+		txmode = SF_DMA_MODE;
+		rxmode = SF_DMA_MODE;
 		priv->xstats.threshold = SF_DMA_MODE;
-	} else
-		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE,
+	} else {
+		txmode = tc;
+		rxmode = SF_DMA_MODE;
+	}
+
+	/* configure all channels */
+	if (priv->synopsys_id >= DWMAC_CORE_4_00) {
+		for (chan = 0; chan < rx_channels_count; chan++)
+			priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan,
+						   rxfifosz);
+
+		for (chan = 0; chan < tx_channels_count; chan++)
+			priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan);
+	} else {
+		priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode,
 					rxfifosz);
+	}
 }
 
 /**
@@ -1444,6 +1464,34 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
 }
 
 /**
+ *  stmmac_set_dma_operation_mode - Set DMA operation mode by channel
+ *  @priv: driver private structure
+ *  @txmode: TX operating mode
+ *  @rxmode: RX operating mode
+ *  @chan: channel index
+ *  Description: it is used for configuring of the DMA operation mode in
+ *  runtime in order to program the tx/rx DMA thresholds or Store-And-Forward
+ *  mode.
+ */
+static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode,
+					  u32 rxmode, u32 chan)
+{
+	int rxfifosz = priv->plat->rx_fifo_size;
+
+	if (rxfifosz == 0)
+		rxfifosz = priv->dma_cap.rx_fifo_size;
+
+	if (priv->synopsys_id >= DWMAC_CORE_4_00) {
+		priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan,
+					   rxfifosz);
+		priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan);
+	} else {
+		priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode,
+					rxfifosz);
+	}
+}
+
+/**
  * stmmac_dma_interrupt - DMA ISR
  * @priv: driver private structure
  * Description: this is the DMA ISR. It is called by the main ISR.
@@ -1452,11 +1500,8 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
  */
 static void stmmac_dma_interrupt(struct stmmac_priv *priv)
 {
+	u32 chan = STMMAC_CHAN0;
 	int status;
-	int rxfifosz = priv->plat->rx_fifo_size;
-
-	if (rxfifosz == 0)
-		rxfifosz = priv->dma_cap.rx_fifo_size;
 
 	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
 	if (likely((status & handle_rx)) || (status & handle_tx)) {
@@ -1471,11 +1516,12 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
 		    (tc <= 256)) {
 			tc += 64;
 			if (priv->plat->force_thresh_dma_mode)
-				priv->hw->dma->dma_mode(priv->ioaddr, tc, tc,
-							rxfifosz);
+				stmmac_set_dma_operation_mode(priv->ioaddr,
+							      tc, tc, chan);
 			else
-				priv->hw->dma->dma_mode(priv->ioaddr, tc,
-							SF_DMA_MODE, rxfifosz);
+				stmmac_set_dma_operation_mode(priv->ioaddr, tc,
+							     SF_DMA_MODE, chan);
+
 			priv->xstats.threshold = tc;
 		}
 	} else if (unlikely(status == tx_hard_error))
@@ -1749,6 +1795,9 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
 	/* Enable MAC RX Queues */
 	if (rx_queues_count > 1 && priv->hw->mac->rx_queue_enable)
 		stmmac_mac_enable_rx_queues(priv);
+
+	/* Set the HW DMA mode and the COE */
+	stmmac_dma_operation_mode(priv);
 }
 
 /**
@@ -1812,9 +1861,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 	else
 		stmmac_set_mac(priv->ioaddr, true);
 
-	/* Set the HW DMA mode and the COE */
-	stmmac_dma_operation_mode(priv);
-
 	stmmac_mmc_setup(priv);
 
 	if (init_ptp) {
-- 
2.9.3

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

* [PATCH v3 net-next 02/11] net: stmmac: enable/disable dma irq prepared for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 03/11] net: stmmac: rx/tx dma start/stop " Joao Pinto
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares the DMA IRQ enable/disable process for multiple queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/common.h      |  4 ++--
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h  |  6 +++---
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c  | 12 ++++++------
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h   |  4 ++--
 drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c   |  4 ++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 +++++++------
 6 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 13bd3d4..0351b54 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -431,8 +431,8 @@ struct stmmac_dma_ops {
 	void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
 				   void __iomem *ioaddr);
 	void (*enable_dma_transmission) (void __iomem *ioaddr);
-	void (*enable_dma_irq) (void __iomem *ioaddr);
-	void (*disable_dma_irq) (void __iomem *ioaddr);
+	void (*enable_dma_irq)(void __iomem *ioaddr, u32 chan);
+	void (*disable_dma_irq)(void __iomem *ioaddr, u32 chan);
 	void (*start_tx) (void __iomem *ioaddr);
 	void (*stop_tx) (void __iomem *ioaddr);
 	void (*start_rx) (void __iomem *ioaddr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index 1b06df7..393a657 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -185,9 +185,9 @@
 
 int dwmac4_dma_reset(void __iomem *ioaddr);
 void dwmac4_enable_dma_transmission(void __iomem *ioaddr, u32 tail_ptr);
-void dwmac4_enable_dma_irq(void __iomem *ioaddr);
-void dwmac410_enable_dma_irq(void __iomem *ioaddr);
-void dwmac4_disable_dma_irq(void __iomem *ioaddr);
+void dwmac4_enable_dma_irq(void __iomem *ioaddr, u32 chan);
+void dwmac410_enable_dma_irq(void __iomem *ioaddr, u32 chan);
+void dwmac4_disable_dma_irq(void __iomem *ioaddr, u32 chan);
 void dwmac4_dma_start_tx(void __iomem *ioaddr);
 void dwmac4_dma_stop_tx(void __iomem *ioaddr);
 void dwmac4_dma_start_rx(void __iomem *ioaddr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index c7326d5..c932791 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -104,21 +104,21 @@ void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len)
 	writel(len, ioaddr + DMA_CHAN_RX_RING_LEN(STMMAC_CHAN0));
 }
 
-void dwmac4_enable_dma_irq(void __iomem *ioaddr)
+void dwmac4_enable_dma_irq(void __iomem *ioaddr, u32 chan)
 {
 	writel(DMA_CHAN_INTR_DEFAULT_MASK, ioaddr +
-	       DMA_CHAN_INTR_ENA(STMMAC_CHAN0));
+	       DMA_CHAN_INTR_ENA(chan));
 }
 
-void dwmac410_enable_dma_irq(void __iomem *ioaddr)
+void dwmac410_enable_dma_irq(void __iomem *ioaddr, u32 chan)
 {
 	writel(DMA_CHAN_INTR_DEFAULT_MASK_4_10,
-	       ioaddr + DMA_CHAN_INTR_ENA(STMMAC_CHAN0));
+	       ioaddr + DMA_CHAN_INTR_ENA(chan));
 }
 
-void dwmac4_disable_dma_irq(void __iomem *ioaddr)
+void dwmac4_disable_dma_irq(void __iomem *ioaddr, u32 chan)
 {
-	writel(0, ioaddr + DMA_CHAN_INTR_ENA(STMMAC_CHAN0));
+	writel(0, ioaddr + DMA_CHAN_INTR_ENA(chan));
 }
 
 int dwmac4_dma_interrupt(void __iomem *ioaddr,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 56e485f..dec0816 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -137,8 +137,8 @@
 #define DMA_CONTROL_FTF		0x00100000	/* Flush transmit FIFO */
 
 void dwmac_enable_dma_transmission(void __iomem *ioaddr);
-void dwmac_enable_dma_irq(void __iomem *ioaddr);
-void dwmac_disable_dma_irq(void __iomem *ioaddr);
+void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan);
+void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan);
 void dwmac_dma_start_tx(void __iomem *ioaddr);
 void dwmac_dma_stop_tx(void __iomem *ioaddr);
 void dwmac_dma_start_rx(void __iomem *ioaddr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index e60bfca..285cfc9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -47,12 +47,12 @@ void dwmac_enable_dma_transmission(void __iomem *ioaddr)
 	writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
 }
 
-void dwmac_enable_dma_irq(void __iomem *ioaddr)
+void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan)
 {
 	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
 }
 
-void dwmac_disable_dma_irq(void __iomem *ioaddr)
+void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan)
 {
 	writel(0, ioaddr + DMA_INTR_ENA);
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c4e4a53..18cf58c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1422,14 +1422,14 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)
 	netif_tx_unlock(priv->dev);
 }
 
-static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv)
+static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv, u32 chan)
 {
-	priv->hw->dma->enable_dma_irq(priv->ioaddr);
+	priv->hw->dma->enable_dma_irq(priv->ioaddr, chan);
 }
 
-static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv)
+static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv, u32 chan)
 {
-	priv->hw->dma->disable_dma_irq(priv->ioaddr);
+	priv->hw->dma->disable_dma_irq(priv->ioaddr, chan);
 }
 
 /**
@@ -1506,7 +1506,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
 	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
 	if (likely((status & handle_rx)) || (status & handle_tx)) {
 		if (likely(napi_schedule_prep(&priv->napi))) {
-			stmmac_disable_dma_irq(priv);
+			stmmac_disable_dma_irq(priv, chan);
 			__napi_schedule(&priv->napi);
 		}
 	}
@@ -2832,6 +2832,7 @@ static int stmmac_poll(struct napi_struct *napi, int budget)
 {
 	struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
 	int work_done = 0;
+	u32 chan = STMMAC_CHAN0;
 
 	priv->xstats.napi_poll++;
 	stmmac_tx_clean(priv);
@@ -2839,7 +2840,7 @@ static int stmmac_poll(struct napi_struct *napi, int budget)
 	work_done = stmmac_rx(priv, budget);
 	if (work_done < budget) {
 		napi_complete_done(napi, work_done);
-		stmmac_enable_dma_irq(priv);
+		stmmac_enable_dma_irq(priv, chan);
 	}
 	return work_done;
 }
-- 
2.9.3

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

* [PATCH v3 net-next 03/11] net: stmmac: rx/tx dma start/stop prepared for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config " Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 02/11] net: stmmac: enable/disable dma irq prepared " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 04/11] net: stmmac: prepare stmmac_tx_err " Joao Pinto
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares the RX/TX DMA stop/start process for multiple queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/common.h      |   8 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h  |   8 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c  |  24 ++---
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h   |   8 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c   |   8 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 108 +++++++++++++++++++---
 6 files changed, 125 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 0351b54..042b482 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -433,10 +433,10 @@ struct stmmac_dma_ops {
 	void (*enable_dma_transmission) (void __iomem *ioaddr);
 	void (*enable_dma_irq)(void __iomem *ioaddr, u32 chan);
 	void (*disable_dma_irq)(void __iomem *ioaddr, u32 chan);
-	void (*start_tx) (void __iomem *ioaddr);
-	void (*stop_tx) (void __iomem *ioaddr);
-	void (*start_rx) (void __iomem *ioaddr);
-	void (*stop_rx) (void __iomem *ioaddr);
+	void (*start_tx)(void __iomem *ioaddr, u32 chan);
+	void (*stop_tx)(void __iomem *ioaddr, u32 chan);
+	void (*start_rx)(void __iomem *ioaddr, u32 chan);
+	void (*stop_rx)(void __iomem *ioaddr, u32 chan);
 	int (*dma_interrupt) (void __iomem *ioaddr,
 			      struct stmmac_extra_stats *x);
 	/* If supported then get the optional core features */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index 393a657..2c19042 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -188,10 +188,10 @@ void dwmac4_enable_dma_transmission(void __iomem *ioaddr, u32 tail_ptr);
 void dwmac4_enable_dma_irq(void __iomem *ioaddr, u32 chan);
 void dwmac410_enable_dma_irq(void __iomem *ioaddr, u32 chan);
 void dwmac4_disable_dma_irq(void __iomem *ioaddr, u32 chan);
-void dwmac4_dma_start_tx(void __iomem *ioaddr);
-void dwmac4_dma_stop_tx(void __iomem *ioaddr);
-void dwmac4_dma_start_rx(void __iomem *ioaddr);
-void dwmac4_dma_stop_rx(void __iomem *ioaddr);
+void dwmac4_dma_start_tx(void __iomem *ioaddr, u32 chan);
+void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan);
+void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan);
+void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan);
 int dwmac4_dma_interrupt(void __iomem *ioaddr,
 			 struct stmmac_extra_stats *x);
 void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index c932791..3512d18 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -45,49 +45,49 @@ void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan)
 	writel(tail_ptr, ioaddr + DMA_CHAN_TX_END_ADDR(0));
 }
 
-void dwmac4_dma_start_tx(void __iomem *ioaddr)
+void dwmac4_dma_start_tx(void __iomem *ioaddr, u32 chan)
 {
-	u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0));
+	u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
 
 	value |= DMA_CONTROL_ST;
-	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0));
+	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
 
 	value = readl(ioaddr + GMAC_CONFIG);
 	value |= GMAC_CONFIG_TE;
 	writel(value, ioaddr + GMAC_CONFIG);
 }
 
-void dwmac4_dma_stop_tx(void __iomem *ioaddr)
+void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan)
 {
-	u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0));
+	u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
 
 	value &= ~DMA_CONTROL_ST;
-	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0));
+	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
 
 	value = readl(ioaddr + GMAC_CONFIG);
 	value &= ~GMAC_CONFIG_TE;
 	writel(value, ioaddr + GMAC_CONFIG);
 }
 
-void dwmac4_dma_start_rx(void __iomem *ioaddr)
+void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan)
 {
-	u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0));
+	u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
 
 	value |= DMA_CONTROL_SR;
 
-	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0));
+	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
 
 	value = readl(ioaddr + GMAC_CONFIG);
 	value |= GMAC_CONFIG_RE;
 	writel(value, ioaddr + GMAC_CONFIG);
 }
 
-void dwmac4_dma_stop_rx(void __iomem *ioaddr)
+void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan)
 {
-	u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0));
+	u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
 
 	value &= ~DMA_CONTROL_SR;
-	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0));
+	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
 
 	value = readl(ioaddr + GMAC_CONFIG);
 	value &= ~GMAC_CONFIG_RE;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index dec0816..6c6cc71 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -139,10 +139,10 @@
 void dwmac_enable_dma_transmission(void __iomem *ioaddr);
 void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan);
 void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan);
-void dwmac_dma_start_tx(void __iomem *ioaddr);
-void dwmac_dma_stop_tx(void __iomem *ioaddr);
-void dwmac_dma_start_rx(void __iomem *ioaddr);
-void dwmac_dma_stop_rx(void __iomem *ioaddr);
+void dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan);
+void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan);
+void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan);
+void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan);
 int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x);
 int dwmac_dma_reset(void __iomem *ioaddr);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index 285cfc9..7be60c3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -57,28 +57,28 @@ void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan)
 	writel(0, ioaddr + DMA_INTR_ENA);
 }
 
-void dwmac_dma_start_tx(void __iomem *ioaddr)
+void dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan)
 {
 	u32 value = readl(ioaddr + DMA_CONTROL);
 	value |= DMA_CONTROL_ST;
 	writel(value, ioaddr + DMA_CONTROL);
 }
 
-void dwmac_dma_stop_tx(void __iomem *ioaddr)
+void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan)
 {
 	u32 value = readl(ioaddr + DMA_CONTROL);
 	value &= ~DMA_CONTROL_ST;
 	writel(value, ioaddr + DMA_CONTROL);
 }
 
-void dwmac_dma_start_rx(void __iomem *ioaddr)
+void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan)
 {
 	u32 value = readl(ioaddr + DMA_CONTROL);
 	value |= DMA_CONTROL_SR;
 	writel(value, ioaddr + DMA_CONTROL);
 }
 
-void dwmac_dma_stop_rx(void __iomem *ioaddr)
+void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
 {
 	u32 value = readl(ioaddr + DMA_CONTROL);
 	value &= ~DMA_CONTROL_SR;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 18cf58c..a537276 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1278,6 +1278,96 @@ static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
 }
 
 /**
+ * stmmac_start_rx_dma - start RX DMA channel
+ * @priv: driver private structure
+ * @chan: RX channel index
+ * Description:
+ * This starts a RX DMA channel
+ */
+static void stmmac_start_rx_dma(struct stmmac_priv *priv, u32 chan)
+{
+	netdev_dbg(priv->dev, "DMA RX processes started in channel %d\n", chan);
+	priv->hw->dma->start_rx(priv->ioaddr, chan);
+}
+
+/**
+ * stmmac_start_tx_dma - start TX DMA channel
+ * @priv: driver private structure
+ * @chan: TX channel index
+ * Description:
+ * This starts a TX DMA channel
+ */
+static void stmmac_start_tx_dma(struct stmmac_priv *priv, u32 chan)
+{
+	netdev_dbg(priv->dev, "DMA TX processes started in channel %d\n", chan);
+	priv->hw->dma->start_tx(priv->ioaddr, chan);
+}
+
+/**
+ * stmmac_stop_rx_dma - stop RX DMA channel
+ * @priv: driver private structure
+ * @chan: RX channel index
+ * Description:
+ * This stops a RX DMA channel
+ */
+static void stmmac_stop_rx_dma(struct stmmac_priv *priv, u32 chan)
+{
+	netdev_dbg(priv->dev, "DMA RX processes stopped in channel %d\n", chan);
+	priv->hw->dma->stop_rx(priv->ioaddr, chan);
+}
+
+/**
+ * stmmac_stop_tx_dma - stop TX DMA channel
+ * @priv: driver private structure
+ * @chan: TX channel index
+ * Description:
+ * This stops a TX DMA channel
+ */
+static void stmmac_stop_tx_dma(struct stmmac_priv *priv, u32 chan)
+{
+	netdev_dbg(priv->dev, "DMA TX processes stopped in channel %d\n", chan);
+	priv->hw->dma->stop_tx(priv->ioaddr, chan);
+}
+
+/**
+ * stmmac_start_all_dma - start all RX and TX DMA channels
+ * @priv: driver private structure
+ * Description:
+ * This starts all the RX and TX DMA channels
+ */
+static void stmmac_start_all_dma(struct stmmac_priv *priv)
+{
+	u32 rx_channels_count = priv->plat->rx_queues_to_use;
+	u32 tx_channels_count = priv->plat->tx_queues_to_use;
+	u32 chan = 0;
+
+	for (chan = 0; chan < rx_channels_count; chan++)
+		stmmac_start_rx_dma(priv, chan);
+
+	for (chan = 0; chan < tx_channels_count; chan++)
+		stmmac_start_tx_dma(priv, chan);
+}
+
+/**
+ * stmmac_stop_all_dma - stop all RX and TX DMA channels
+ * @priv: driver private structure
+ * Description:
+ * This stops the RX and TX DMA channels
+ */
+static void stmmac_stop_all_dma(struct stmmac_priv *priv)
+{
+	u32 rx_channels_count = priv->plat->rx_queues_to_use;
+	u32 tx_channels_count = priv->plat->tx_queues_to_use;
+	u32 chan = 0;
+
+	for (chan = 0; chan < rx_channels_count; chan++)
+		stmmac_stop_rx_dma(priv, chan);
+
+	for (chan = 0; chan < tx_channels_count; chan++)
+		stmmac_stop_tx_dma(priv, chan);
+}
+
+/**
  *  stmmac_dma_operation_mode - HW DMA operation mode
  *  @priv: driver private structure
  *  Description: it is used for configuring the DMA operation mode register in
@@ -1440,10 +1530,11 @@ static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv, u32 chan)
  */
 static void stmmac_tx_err(struct stmmac_priv *priv)
 {
+	u32 chan = STMMAC_CHAN0;
 	int i;
 	netif_stop_queue(priv->dev);
 
-	priv->hw->dma->stop_tx(priv->ioaddr);
+	stmmac_stop_tx_dma(priv, chan);
 	dma_free_tx_skbufs(priv);
 	for (i = 0; i < DMA_TX_SIZE; i++)
 		if (priv->extend_desc)
@@ -1457,7 +1548,7 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
 	priv->dirty_tx = 0;
 	priv->cur_tx = 0;
 	netdev_reset_queue(priv->dev);
-	priv->hw->dma->start_tx(priv->ioaddr);
+	stmmac_start_tx_dma(priv, chan);
 
 	priv->dev->stats.tx_errors++;
 	netif_wake_queue(priv->dev);
@@ -1882,9 +1973,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 			    __func__);
 #endif
 	/* Start the ball rolling... */
-	netdev_dbg(priv->dev, "DMA RX/TX processes started...\n");
-	priv->hw->dma->start_tx(priv->ioaddr);
-	priv->hw->dma->start_rx(priv->ioaddr);
+	stmmac_start_all_dma(priv);
 
 	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
 
@@ -2070,8 +2159,7 @@ static int stmmac_release(struct net_device *dev)
 		free_irq(priv->lpi_irq, dev);
 
 	/* Stop TX/RX DMA and clear the descriptors */
-	priv->hw->dma->stop_tx(priv->ioaddr);
-	priv->hw->dma->stop_rx(priv->ioaddr);
+	stmmac_stop_all_dma(priv);
 
 	/* Release and free the Rx/Tx resources */
 	free_dma_desc_resources(priv);
@@ -3546,8 +3634,7 @@ int stmmac_dvr_remove(struct device *dev)
 
 	netdev_info(priv->dev, "%s: removing driver", __func__);
 
-	priv->hw->dma->stop_rx(priv->ioaddr);
-	priv->hw->dma->stop_tx(priv->ioaddr);
+	stmmac_stop_all_dma(priv);
 
 	stmmac_set_mac(priv->ioaddr, false);
 	netif_carrier_off(ndev);
@@ -3593,8 +3680,7 @@ int stmmac_suspend(struct device *dev)
 	napi_disable(&priv->napi);
 
 	/* Stop TX/RX DMA */
-	priv->hw->dma->stop_tx(priv->ioaddr);
-	priv->hw->dma->stop_rx(priv->ioaddr);
+	stmmac_stop_all_dma(priv);
 
 	/* Enable Power down mode by programming the PMT regs */
 	if (device_may_wakeup(priv->device)) {
-- 
2.9.3

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

* [PATCH v3 net-next 04/11] net: stmmac: prepare stmmac_tx_err for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (2 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 03/11] net: stmmac: rx/tx dma start/stop " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 05/11] net: stmmac: prepare dma interrupt treatment " Joao Pinto
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares stmmac_err for multiple queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a537276..b166c05 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1525,12 +1525,12 @@ static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv, u32 chan)
 /**
  * stmmac_tx_err - to manage the tx error
  * @priv: driver private structure
+ * @chan: channel index
  * Description: it cleans the descriptors and restarts the transmission
  * in case of transmission errors.
  */
-static void stmmac_tx_err(struct stmmac_priv *priv)
+static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan)
 {
-	u32 chan = STMMAC_CHAN0;
 	int i;
 	netif_stop_queue(priv->dev);
 
@@ -1616,7 +1616,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
 			priv->xstats.threshold = tc;
 		}
 	} else if (unlikely(status == tx_hard_error))
-		stmmac_tx_err(priv);
+		stmmac_tx_err(priv, chan);
 }
 
 /**
@@ -2944,9 +2944,10 @@ static int stmmac_poll(struct napi_struct *napi, int budget)
 static void stmmac_tx_timeout(struct net_device *dev)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
+	u32 chan = STMMAC_CHAN0;
 
 	/* Clear Tx resources and restart transmitting again */
-	stmmac_tx_err(priv);
+	stmmac_tx_err(priv, chan);
 }
 
 /**
-- 
2.9.3

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

* [PATCH v3 net-next 05/11] net: stmmac: prepare dma interrupt treatment for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (3 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 04/11] net: stmmac: prepare stmmac_tx_err " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 06/11] net: stmmac: rx watchdog config prepared " Joao Pinto
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares DMA interrupts treatment for multiple queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v2->v3:
- patch was not being applied cleanly
changes v1->v2:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/common.h      |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c  |  8 ++--
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h   |  3 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 51 +++++++++++++----------
 6 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 042b482..6dfb7f3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -438,7 +438,7 @@ struct stmmac_dma_ops {
 	void (*start_rx)(void __iomem *ioaddr, u32 chan);
 	void (*stop_rx)(void __iomem *ioaddr, u32 chan);
 	int (*dma_interrupt) (void __iomem *ioaddr,
-			      struct stmmac_extra_stats *x);
+			      struct stmmac_extra_stats *x, u32 chan);
 	/* If supported then get the optional core features */
 	void (*get_hw_feature)(void __iomem *ioaddr,
 			       struct dma_features *dma_cap);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index 2c19042..946dc14 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -193,7 +193,7 @@ void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan);
 void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan);
 void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan);
 int dwmac4_dma_interrupt(void __iomem *ioaddr,
-			 struct stmmac_extra_stats *x);
+			 struct stmmac_extra_stats *x, u32 chan);
 void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len);
 void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len);
 void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index 3512d18..fcd8ec8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -122,11 +122,11 @@ void dwmac4_disable_dma_irq(void __iomem *ioaddr, u32 chan)
 }
 
 int dwmac4_dma_interrupt(void __iomem *ioaddr,
-			 struct stmmac_extra_stats *x)
+			 struct stmmac_extra_stats *x, u32 chan)
 {
 	int ret = 0;
 
-	u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(0));
+	u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(chan));
 
 	/* ABNORMAL interrupts */
 	if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) {
@@ -153,7 +153,7 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
 		if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
 			u32 value;
 
-			value = readl(ioaddr + DMA_CHAN_INTR_ENA(STMMAC_CHAN0));
+			value = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
 			/* to schedule NAPI on real RIE event. */
 			if (likely(value & DMA_CHAN_INTR_ENA_RIE)) {
 				x->rx_normal_irq_n++;
@@ -172,7 +172,7 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
 	 * status [21-0] expect reserved bits [5-3]
 	 */
 	writel((intr_status & 0x3fffc7),
-	       ioaddr + DMA_CHAN_STATUS(STMMAC_CHAN0));
+	       ioaddr + DMA_CHAN_STATUS(chan));
 
 	return ret;
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 6c6cc71..9091df8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -143,7 +143,8 @@ void dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan);
 void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan);
 void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan);
 void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan);
-int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x);
+int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x,
+			u32 chan);
 int dwmac_dma_reset(void __iomem *ioaddr);
 
 #endif /* __DWMAC_DMA_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index 7be60c3..38f9430 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -156,7 +156,7 @@ static void show_rx_process_state(unsigned int status)
 #endif
 
 int dwmac_dma_interrupt(void __iomem *ioaddr,
-			struct stmmac_extra_stats *x)
+			struct stmmac_extra_stats *x, u32 chan)
 {
 	int ret = 0;
 	/* read the status register (CSR5) */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b166c05..79a792a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1591,32 +1591,41 @@ static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode,
  */
 static void stmmac_dma_interrupt(struct stmmac_priv *priv)
 {
-	u32 chan = STMMAC_CHAN0;
+	u32 tx_channel_count = priv->plat->tx_queues_to_use;
 	int status;
+	u32 chan;
 
-	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
-	if (likely((status & handle_rx)) || (status & handle_tx)) {
-		if (likely(napi_schedule_prep(&priv->napi))) {
-			stmmac_disable_dma_irq(priv, chan);
-			__napi_schedule(&priv->napi);
+	for (chan = 0; chan < tx_channel_count; chan++) {
+		status = priv->hw->dma->dma_interrupt(priv->ioaddr,
+						      &priv->xstats, chan);
+		if (likely((status & handle_rx)) || (status & handle_tx)) {
+			if (likely(napi_schedule_prep(&priv->napi))) {
+				stmmac_disable_dma_irq(priv, chan);
+				__napi_schedule(&priv->napi);
+			}
 		}
-	}
-	if (unlikely(status & tx_hard_error_bump_tc)) {
-		/* Try to bump up the dma threshold on this failure */
-		if (unlikely(priv->xstats.threshold != SF_DMA_MODE) &&
-		    (tc <= 256)) {
-			tc += 64;
-			if (priv->plat->force_thresh_dma_mode)
-				stmmac_set_dma_operation_mode(priv->ioaddr,
-							      tc, tc, chan);
-			else
-				stmmac_set_dma_operation_mode(priv->ioaddr, tc,
-							     SF_DMA_MODE, chan);
 
-			priv->xstats.threshold = tc;
+		if (unlikely(status & tx_hard_error_bump_tc)) {
+			/* Try to bump up the dma threshold on this failure */
+			if (unlikely(priv->xstats.threshold != SF_DMA_MODE) &&
+			    (tc <= 256)) {
+				tc += 64;
+				if (priv->plat->force_thresh_dma_mode)
+					stmmac_set_dma_operation_mode(priv,
+								      tc,
+								      tc,
+								      chan);
+				else
+					stmmac_set_dma_operation_mode(priv,
+								    tc,
+								    SF_DMA_MODE,
+								    chan);
+				priv->xstats.threshold = tc;
+			}
+		} else if (unlikely(status == tx_hard_error)) {
+			stmmac_tx_err(priv, chan);
 		}
-	} else if (unlikely(status == tx_hard_error))
-		stmmac_tx_err(priv, chan);
+	}
 }
 
 /**
-- 
2.9.3

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

* [PATCH v3 net-next 06/11] net: stmmac: rx watchdog config prepared for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (4 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 05/11] net: stmmac: prepare dma interrupt treatment " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 07/11] net: stmmac: rx and tx ring length " Joao Pinto
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch adds rx watchdog configuration for all queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/common.h         | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c  | 3 ++-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c     | 8 ++++----
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 3 ++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c    | 3 ++-
 5 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 6dfb7f3..5fa23b1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -443,7 +443,7 @@ struct stmmac_dma_ops {
 	void (*get_hw_feature)(void __iomem *ioaddr,
 			       struct dma_features *dma_cap);
 	/* Program the HW RX Watchdog */
-	void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt);
+	void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt, u32 number_chan);
 	void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len);
 	void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len);
 	void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index d3654a4..471a9aa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -247,7 +247,8 @@ static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
 	dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
 }
 
-static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt)
+static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
+				  u32 number_chan)
 {
 	writel(riwt, ioaddr + DMA_RX_WATCHDOG);
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 6285e8a..74177f9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -174,12 +174,12 @@ static void dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
 		_dwmac4_dump_dma_regs(ioaddr, i, reg_space);
 }
 
-static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt)
+static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 number_chan)
 {
-	int i;
+	u32 chan;
 
-	for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
-		writel(riwt, ioaddr + DMA_CHAN_RX_WATCHDOG(i));
+	for (chan = 0; chan < number_chan; chan++)
+		writel(riwt, ioaddr + DMA_CHAN_RX_WATCHDOG(chan));
 }
 
 static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 61b9369..16808e4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -730,6 +730,7 @@ static int stmmac_set_coalesce(struct net_device *dev,
 			       struct ethtool_coalesce *ec)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
+	u32 rx_cnt = priv->plat->rx_queues_to_use;
 	unsigned int rx_riwt;
 
 	/* Check not supported parameters  */
@@ -768,7 +769,7 @@ static int stmmac_set_coalesce(struct net_device *dev,
 	priv->tx_coal_frames = ec->tx_max_coalesced_frames;
 	priv->tx_coal_timer = ec->tx_coalesce_usecs;
 	priv->rx_riwt = rx_riwt;
-	priv->hw->dma->rx_watchdog(priv->ioaddr, priv->rx_riwt);
+	priv->hw->dma->rx_watchdog(priv->ioaddr, priv->rx_riwt, rx_cnt);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 79a792a..00d0f5e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1915,6 +1915,7 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
 static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
+	u32 rx_cnt = priv->plat->rx_queues_to_use;
 	int ret;
 
 	/* DMA initialization and SW reset */
@@ -1988,7 +1989,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 
 	if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
 		priv->rx_riwt = MAX_DMA_RIWT;
-		priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
+		priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT, rx_cnt);
 	}
 
 	if (priv->hw->pcs && priv->hw->mac->pcs_ctrl_ane)
-- 
2.9.3

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

* [PATCH v3 net-next 07/11] net: stmmac: rx and tx ring length prepared for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (5 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 06/11] net: stmmac: rx watchdog config prepared " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 08/11] net: stmmac: prepare rx/tx set tail function " Joao Pinto
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares tx and rx ring length configuration for multiple queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/common.h      |  4 +--
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h  |  4 +--
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c  |  8 +++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 32 +++++++++++++++++------
 4 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 5fa23b1..bef1fc6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -444,8 +444,8 @@ struct stmmac_dma_ops {
 			       struct dma_features *dma_cap);
 	/* Program the HW RX Watchdog */
 	void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt, u32 number_chan);
-	void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len);
-	void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len);
+	void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
+	void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
 	void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
 	void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
 	void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index 946dc14..8474bf9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -194,8 +194,8 @@ void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan);
 void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan);
 int dwmac4_dma_interrupt(void __iomem *ioaddr,
 			 struct stmmac_extra_stats *x, u32 chan);
-void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len);
-void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len);
+void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan);
+void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan);
 void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
 void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index fcd8ec8..da54c0b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -94,14 +94,14 @@ void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan)
 	writel(value, ioaddr + GMAC_CONFIG);
 }
 
-void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len)
+void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
 {
-	writel(len, ioaddr + DMA_CHAN_TX_RING_LEN(STMMAC_CHAN0));
+	writel(len, ioaddr + DMA_CHAN_TX_RING_LEN(chan));
 }
 
-void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len)
+void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
 {
-	writel(len, ioaddr + DMA_CHAN_RX_RING_LEN(STMMAC_CHAN0));
+	writel(len, ioaddr + DMA_CHAN_RX_RING_LEN(chan));
 }
 
 void dwmac4_enable_dma_irq(void __iomem *ioaddr, u32 chan)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 00d0f5e..26695d9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1802,6 +1802,27 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
 	add_timer(&priv->txtimer);
 }
 
+static void stmmac_set_rings_length(struct stmmac_priv *priv)
+{
+	u32 rx_channels_count = priv->plat->rx_queues_to_use;
+	u32 tx_channels_count = priv->plat->tx_queues_to_use;
+	u32 chan;
+
+	/* set TX ring length */
+	if (priv->hw->dma->set_tx_ring_len) {
+		for (chan = 0; chan < tx_channels_count; chan++)
+			priv->hw->dma->set_tx_ring_len(priv->ioaddr,
+						       (DMA_TX_SIZE - 1), chan);
+	}
+
+	/* set RX ring length */
+	if (priv->hw->dma->set_rx_ring_len) {
+		for (chan = 0; chan < rx_channels_count; chan++)
+			priv->hw->dma->set_rx_ring_len(priv->ioaddr,
+						       (DMA_RX_SIZE - 1), chan);
+	}
+}
+
 /**
  *  stmmac_set_tx_queue_weight - Set TX queue weight
  *  @priv: driver private structure
@@ -1995,14 +2016,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 	if (priv->hw->pcs && priv->hw->mac->pcs_ctrl_ane)
 		priv->hw->mac->pcs_ctrl_ane(priv->hw, 1, priv->hw->ps, 0);
 
-	/*  set TX ring length */
-	if (priv->hw->dma->set_tx_ring_len)
-		priv->hw->dma->set_tx_ring_len(priv->ioaddr,
-					       (DMA_TX_SIZE - 1));
-	/*  set RX ring length */
-	if (priv->hw->dma->set_rx_ring_len)
-		priv->hw->dma->set_rx_ring_len(priv->ioaddr,
-					       (DMA_RX_SIZE - 1));
+	/* set TX and RX rings length */
+	stmmac_set_rings_length(priv);
+
 	/* Enable TSO */
 	if (priv->tso)
 		priv->hw->dma->enable_tso(priv->ioaddr, 1, STMMAC_CHAN0);
-- 
2.9.3

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

* [PATCH v3 net-next 08/11] net: stmmac: prepare rx/tx set tail function for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (6 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 07/11] net: stmmac: rx and tx ring length " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 09/11] net: stmmac: dma channel init prepared " Joao Pinto
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares RX and TX set tail functions for multiple queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index da54c0b..49f5687 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -37,12 +37,12 @@ int dwmac4_dma_reset(void __iomem *ioaddr)
 
 void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan)
 {
-	writel(tail_ptr, ioaddr + DMA_CHAN_RX_END_ADDR(0));
+	writel(tail_ptr, ioaddr + DMA_CHAN_RX_END_ADDR(chan));
 }
 
 void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan)
 {
-	writel(tail_ptr, ioaddr + DMA_CHAN_TX_END_ADDR(0));
+	writel(tail_ptr, ioaddr + DMA_CHAN_TX_END_ADDR(chan));
 }
 
 void dwmac4_dma_start_tx(void __iomem *ioaddr, u32 chan)
-- 
2.9.3

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

* [PATCH v3 net-next 09/11] net: stmmac: dma channel init prepared for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (7 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 08/11] net: stmmac: prepare rx/tx set tail function " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 10/11] net: stmmac: tso " Joao Pinto
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares the DMA initialization process for multiple queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v2->v3:
- Just to keep up the patch-set version
changes v1->v2:
- dummy_dma_rx_phy was not being initialized

 drivers/net/ethernet/stmicro/stmmac/common.h      |  8 +++
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c  | 66 ++++++++++++++---------
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 51 ++++++++++++++----
 3 files changed, 88 insertions(+), 37 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index bef1fc6..badc441 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -416,6 +416,14 @@ struct stmmac_dma_ops {
 	int (*reset)(void __iomem *ioaddr);
 	void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
 		     u32 dma_tx, u32 dma_rx, int atds);
+	void (*init_chan)(void __iomem *ioaddr,
+			  struct stmmac_dma_cfg *dma_cfg, u32 chan);
+	void (*init_rx_chan)(void __iomem *ioaddr,
+			     struct stmmac_dma_cfg *dma_cfg,
+			     u32 dma_rx_phy, u32 chan);
+	void (*init_tx_chan)(void __iomem *ioaddr,
+			     struct stmmac_dma_cfg *dma_cfg,
+			     u32 dma_tx_phy, u32 chan);
 	/* Configure the AXI Bus Mode Register */
 	void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi);
 	/* Dump DMA registers */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 74177f9..eec8463 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -71,36 +71,48 @@ static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
 	writel(value, ioaddr + DMA_SYS_BUS_MODE);
 }
 
-static void dwmac4_dma_init_channel(void __iomem *ioaddr,
-				    struct stmmac_dma_cfg *dma_cfg,
-				    u32 dma_tx_phy, u32 dma_rx_phy,
-				    u32 channel)
+void dwmac4_dma_init_rx_chan(void __iomem *ioaddr,
+			     struct stmmac_dma_cfg *dma_cfg,
+			     u32 dma_rx_phy, u32 chan)
 {
 	u32 value;
-	int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
-	int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
+	u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
 
-	/* set PBL for each channels. Currently we affect same configuration
-	 * on each channel
-	 */
-	value = readl(ioaddr + DMA_CHAN_CONTROL(channel));
-	if (dma_cfg->pblx8)
-		value = value | DMA_BUS_MODE_PBL;
-	writel(value, ioaddr + DMA_CHAN_CONTROL(channel));
+	value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
+	value = value | (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
+	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
+
+	writel(dma_rx_phy, ioaddr + DMA_CHAN_RX_BASE_ADDR(chan));
+}
 
-	value = readl(ioaddr + DMA_CHAN_TX_CONTROL(channel));
+void dwmac4_dma_init_tx_chan(void __iomem *ioaddr,
+			     struct stmmac_dma_cfg *dma_cfg,
+			     u32 dma_tx_phy, u32 chan)
+{
+	u32 value;
+	u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
+
+	value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
 	value = value | (txpbl << DMA_BUS_MODE_PBL_SHIFT);
-	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(channel));
+	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
 
-	value = readl(ioaddr + DMA_CHAN_RX_CONTROL(channel));
-	value = value | (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
-	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(channel));
+	writel(dma_tx_phy, ioaddr + DMA_CHAN_TX_BASE_ADDR(chan));
+}
 
-	/* Mask interrupts by writing to CSR7 */
-	writel(DMA_CHAN_INTR_DEFAULT_MASK, ioaddr + DMA_CHAN_INTR_ENA(channel));
+void dwmac4_dma_init_channel(void __iomem *ioaddr,
+			     struct stmmac_dma_cfg *dma_cfg, u32 chan)
+{
+	u32 value;
+
+	/* common channel control register config */
+	value = readl(ioaddr + DMA_CHAN_CONTROL(chan));
+	if (dma_cfg->pblx8)
+		value = value | DMA_BUS_MODE_PBL;
+	writel(value, ioaddr + DMA_CHAN_CONTROL(chan));
 
-	writel(dma_tx_phy, ioaddr + DMA_CHAN_TX_BASE_ADDR(channel));
-	writel(dma_rx_phy, ioaddr + DMA_CHAN_RX_BASE_ADDR(channel));
+	/* Mask interrupts by writing to CSR7 */
+	writel(DMA_CHAN_INTR_DEFAULT_MASK,
+	       ioaddr + DMA_CHAN_INTR_ENA(chan));
 }
 
 static void dwmac4_dma_init(void __iomem *ioaddr,
@@ -108,7 +120,6 @@ static void dwmac4_dma_init(void __iomem *ioaddr,
 			    u32 dma_tx, u32 dma_rx, int atds)
 {
 	u32 value = readl(ioaddr + DMA_SYS_BUS_MODE);
-	int i;
 
 	/* Set the Fixed burst mode */
 	if (dma_cfg->fixed_burst)
@@ -122,9 +133,6 @@ static void dwmac4_dma_init(void __iomem *ioaddr,
 		value |= DMA_SYS_BUS_AAL;
 
 	writel(value, ioaddr + DMA_SYS_BUS_MODE);
-
-	for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
-		dwmac4_dma_init_channel(ioaddr, dma_cfg, dma_tx, dma_rx, i);
 }
 
 static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel,
@@ -379,6 +387,9 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
 const struct stmmac_dma_ops dwmac4_dma_ops = {
 	.reset = dwmac4_dma_reset,
 	.init = dwmac4_dma_init,
+	.init_chan = dwmac4_dma_init_channel,
+	.init_rx_chan = dwmac4_dma_init_rx_chan,
+	.init_tx_chan = dwmac4_dma_init_tx_chan,
 	.axi = dwmac4_dma_axi,
 	.dump_regs = dwmac4_dump_dma_regs,
 	.dma_rx_mode = dwmac4_dma_rx_chan_op_mode,
@@ -402,6 +413,9 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
 const struct stmmac_dma_ops dwmac410_dma_ops = {
 	.reset = dwmac4_dma_reset,
 	.init = dwmac4_dma_init,
+	.init_chan = dwmac4_dma_init_channel,
+	.init_rx_chan = dwmac4_dma_init_rx_chan,
+	.init_tx_chan = dwmac4_dma_init_tx_chan,
 	.axi = dwmac4_dma_axi,
 	.dump_regs = dwmac4_dump_dma_regs,
 	.dma_rx_mode = dwmac4_dma_rx_chan_op_mode,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 26695d9..2868391 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1732,6 +1732,11 @@ static void stmmac_check_ether_addr(struct stmmac_priv *priv)
  */
 static int stmmac_init_dma_engine(struct stmmac_priv *priv)
 {
+	u32 rx_channels_count = priv->plat->rx_queues_to_use;
+	u32 tx_channels_count = priv->plat->tx_queues_to_use;
+	u32 dummy_dma_rx_phy = 0;
+	u32 dummy_dma_tx_phy = 0;
+	u32 chan = 0;
 	int atds = 0;
 	int ret = 0;
 
@@ -1749,19 +1754,43 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
 		return ret;
 	}
 
-	priv->hw->dma->init(priv->ioaddr, priv->plat->dma_cfg,
-			    priv->dma_tx_phy, priv->dma_rx_phy, atds);
-
 	if (priv->synopsys_id >= DWMAC_CORE_4_00) {
-		priv->rx_tail_addr = priv->dma_rx_phy +
-			    (DMA_RX_SIZE * sizeof(struct dma_desc));
-		priv->hw->dma->set_rx_tail_ptr(priv->ioaddr, priv->rx_tail_addr,
-					       STMMAC_CHAN0);
+		/* DMA Configuration */
+		priv->hw->dma->init(priv->ioaddr, priv->plat->dma_cfg,
+				    dummy_dma_tx_phy, dummy_dma_rx_phy, atds);
+
+		/* DMA RX Channel Configuration */
+		for (chan = 0; chan < rx_channels_count; chan++) {
+			priv->hw->dma->init_rx_chan(priv->ioaddr,
+						    priv->plat->dma_cfg,
+						    priv->dma_rx_phy, chan);
+
+			priv->rx_tail_addr = priv->dma_rx_phy +
+				    (DMA_RX_SIZE * sizeof(struct dma_desc));
+			priv->hw->dma->set_rx_tail_ptr(priv->ioaddr,
+						       priv->rx_tail_addr,
+						       chan);
+		}
 
-		priv->tx_tail_addr = priv->dma_tx_phy +
-			    (DMA_TX_SIZE * sizeof(struct dma_desc));
-		priv->hw->dma->set_tx_tail_ptr(priv->ioaddr, priv->tx_tail_addr,
-					       STMMAC_CHAN0);
+		/* DMA TX Channel Configuration */
+		for (chan = 0; chan < tx_channels_count; chan++) {
+			priv->hw->dma->init_chan(priv->ioaddr,
+							priv->plat->dma_cfg,
+							chan);
+
+			priv->hw->dma->init_tx_chan(priv->ioaddr,
+						    priv->plat->dma_cfg,
+						    priv->dma_tx_phy, chan);
+
+			priv->tx_tail_addr = priv->dma_tx_phy +
+				    (DMA_TX_SIZE * sizeof(struct dma_desc));
+			priv->hw->dma->set_tx_tail_ptr(priv->ioaddr,
+						       priv->tx_tail_addr,
+						       chan);
+		}
+	} else {
+		priv->hw->dma->init(priv->ioaddr, priv->plat->dma_cfg,
+				    priv->dma_tx_phy, priv->dma_rx_phy, atds);
 	}
 
 	if (priv->plat->axi && priv->hw->dma->axi)
-- 
2.9.3

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

* [PATCH v3 net-next 10/11] net: stmmac: tso init prepared for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (8 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 09/11] net: stmmac: dma channel init prepared " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 11:04 ` [PATCH v3 net-next 11/11] net: stmmac: stmmac interrupt treatment " Joao Pinto
  2017-03-15 21:44 ` [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations " David Miller
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch configures TSO for all available tx queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 2868391..c802286 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1966,6 +1966,8 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 	u32 rx_cnt = priv->plat->rx_queues_to_use;
+	u32 tx_cnt = priv->plat->tx_queues_to_use;
+	u32 chan;
 	int ret;
 
 	/* DMA initialization and SW reset */
@@ -2049,8 +2051,10 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 	stmmac_set_rings_length(priv);
 
 	/* Enable TSO */
-	if (priv->tso)
-		priv->hw->dma->enable_tso(priv->ioaddr, 1, STMMAC_CHAN0);
+	if (priv->tso) {
+		for (chan = 0; chan < tx_cnt; chan++)
+			priv->hw->dma->enable_tso(priv->ioaddr, 1, chan);
+	}
 
 	return 0;
 }
-- 
2.9.3

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

* [PATCH v3 net-next 11/11] net: stmmac: stmmac interrupt treatment prepared for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (9 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 10/11] net: stmmac: tso " Joao Pinto
@ 2017-03-15 11:04 ` Joao Pinto
  2017-03-15 21:44 ` [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations " David Miller
  11 siblings, 0 replies; 23+ messages in thread
From: Joao Pinto @ 2017-03-15 11:04 UTC (permalink / raw)
  To: davem; +Cc: peppe.cavallaro, alexandre.torgue, netdev, Joao Pinto

This patch prepares the main ISR for multiple queues.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v3:
- Just to keep up the patch-set version

 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 28 ++++++++++++++++-------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c802286..d3a2151 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3115,6 +3115,12 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct stmmac_priv *priv = netdev_priv(dev);
+	u32 rx_cnt = priv->plat->rx_queues_to_use;
+	u32 tx_cnt = priv->plat->tx_queues_to_use;
+	u32 queues_count;
+	u32 queue;
+
+	queues_count = (rx_cnt > tx_cnt) ? rx_cnt : tx_cnt;
 
 	if (priv->irq_wake)
 		pm_wakeup_event(priv->device, 0);
@@ -3129,20 +3135,26 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
 		int status = priv->hw->mac->host_irq_status(priv->hw,
 							    &priv->xstats);
 
-		if (priv->synopsys_id >= DWMAC_CORE_4_00)
-			status |= priv->hw->mac->host_mtl_irq_status(priv->hw,
-								STMMAC_CHAN0);
-
 		if (unlikely(status)) {
 			/* For LPI we need to save the tx status */
 			if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE)
 				priv->tx_path_in_lpi_mode = true;
 			if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE)
 				priv->tx_path_in_lpi_mode = false;
-			if (status & CORE_IRQ_MTL_RX_OVERFLOW && priv->hw->dma->set_rx_tail_ptr)
-				priv->hw->dma->set_rx_tail_ptr(priv->ioaddr,
-							priv->rx_tail_addr,
-							STMMAC_CHAN0);
+		}
+
+		if (priv->synopsys_id >= DWMAC_CORE_4_00) {
+			for (queue = 0; queue < queues_count; queue++) {
+				status |=
+				priv->hw->mac->host_mtl_irq_status(priv->hw,
+								   queue);
+
+				if (status & CORE_IRQ_MTL_RX_OVERFLOW &&
+				    priv->hw->dma->set_rx_tail_ptr)
+					priv->hw->dma->set_rx_tail_ptr(priv->ioaddr,
+								priv->rx_tail_addr,
+								queue);
+			}
 		}
 
 		/* PCS link status */
-- 
2.9.3

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

* Re: [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues
  2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
                   ` (10 preceding siblings ...)
  2017-03-15 11:04 ` [PATCH v3 net-next 11/11] net: stmmac: stmmac interrupt treatment " Joao Pinto
@ 2017-03-15 21:44 ` David Miller
  11 siblings, 0 replies; 23+ messages in thread
From: David Miller @ 2017-03-15 21:44 UTC (permalink / raw)
  To: Joao.Pinto; +Cc: peppe.cavallaro, alexandre.torgue, netdev

From: Joao Pinto <Joao.Pinto@synopsys.com>
Date: Wed, 15 Mar 2017 11:04:44 +0000

> As agreed with David Miller, this patch-set is the second of 3 to enable
> multiple queues in stmmac.
> 
> This second one concentrates on dma operations adding functionalities as:
> a) DMA Operation Mode configuration per channel and done in the multiple
> queues configuration function
> b) DMA IRQ enable and Disable by channel
> c) DMA start and stop by channel
> d) RX and TX ring length configuration by channel
> e) RX and TX set tail pointer by channel
> f) DMA Channel initialization broke into Channel comon, RX and TX
> initialization
> g) TSO being configured for all available channels
> h) DMA interrupt treatment by channel

Series applied.

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-03-15 11:04 ` [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config " Joao Pinto
@ 2017-05-08  6:56   ` Jan Kiszka
  2017-05-08  9:36     ` Andy Shevchenko
  0 siblings, 1 reply; 23+ messages in thread
From: Jan Kiszka @ 2017-05-08  6:56 UTC (permalink / raw)
  To: Joao Pinto, davem
  Cc: peppe.cavallaro, alexandre.torgue, netdev, Linux Kernel Mailing List

On 2017-03-15 12:04, Joao Pinto wrote:
> This patch prepares DMA Operation Mode configuration for multiple queues.
> The work consisted on breaking the DMA operation Mode configuration function
> into RX and TX scope and adapting its mechanism in stmmac_main.
> 
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
> ---
> changes v1->v3:
> - Just to keep up the patch-set version
> 
>  drivers/net/ethernet/stmicro/stmmac/common.h      |   3 +
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c  | 118 +++++++++++-----------
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  82 +++++++++++----
>  3 files changed, 124 insertions(+), 79 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 9f0d26d..13bd3d4 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -424,6 +424,9 @@ struct stmmac_dma_ops {
>  	 * An invalid value enables the store-and-forward mode */
>  	void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode,
>  			 int rxfifosz);
> +	void (*dma_rx_mode)(void __iomem *ioaddr, int mode, u32 channel,
> +			    int fifosz);
> +	void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel);
>  	/* To track extra statistic (if supported) */
>  	void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
>  				   void __iomem *ioaddr);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> index 6ac6b26..6285e8a 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> @@ -182,70 +182,26 @@ static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt)
>  		writel(riwt, ioaddr + DMA_CHAN_RX_WATCHDOG(i));
>  }
>  
> -static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
> -				    int rxmode, u32 channel, int rxfifosz)
> +static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode,
> +				       u32 channel, int fifosz)
>  {
> -	unsigned int rqs = rxfifosz / 256 - 1;
> -	u32 mtl_tx_op, mtl_rx_op, mtl_rx_int;
> -
> -	/* Following code only done for channel 0, other channels not yet
> -	 * supported.
> -	 */
> -	mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));
> -
> -	if (txmode == SF_DMA_MODE) {
> -		pr_debug("GMAC: enable TX store and forward mode\n");
> -		/* Transmit COE type 2 cannot be done in cut-through mode. */
> -		mtl_tx_op |= MTL_OP_MODE_TSF;
> -	} else {
> -		pr_debug("GMAC: disabling TX SF (threshold %d)\n", txmode);
> -		mtl_tx_op &= ~MTL_OP_MODE_TSF;
> -		mtl_tx_op &= MTL_OP_MODE_TTC_MASK;
> -		/* Set the transmit threshold */
> -		if (txmode <= 32)
> -			mtl_tx_op |= MTL_OP_MODE_TTC_32;
> -		else if (txmode <= 64)
> -			mtl_tx_op |= MTL_OP_MODE_TTC_64;
> -		else if (txmode <= 96)
> -			mtl_tx_op |= MTL_OP_MODE_TTC_96;
> -		else if (txmode <= 128)
> -			mtl_tx_op |= MTL_OP_MODE_TTC_128;
> -		else if (txmode <= 192)
> -			mtl_tx_op |= MTL_OP_MODE_TTC_192;
> -		else if (txmode <= 256)
> -			mtl_tx_op |= MTL_OP_MODE_TTC_256;
> -		else if (txmode <= 384)
> -			mtl_tx_op |= MTL_OP_MODE_TTC_384;
> -		else
> -			mtl_tx_op |= MTL_OP_MODE_TTC_512;
> -	}
> -	/* For an IP with DWC_EQOS_NUM_TXQ == 1, the fields TXQEN and TQS are RO
> -	 * with reset values: TXQEN on, TQS == DWC_EQOS_TXFIFO_SIZE.
> -	 * For an IP with DWC_EQOS_NUM_TXQ > 1, the fields TXQEN and TQS are R/W
> -	 * with reset values: TXQEN off, TQS 256 bytes.
> -	 *
> -	 * Write the bits in both cases, since it will have no effect when RO.
> -	 * For DWC_EQOS_NUM_TXQ > 1, the top bits in MTL_OP_MODE_TQS_MASK might
> -	 * be RO, however, writing the whole TQS field will result in a value
> -	 * equal to DWC_EQOS_TXFIFO_SIZE, just like for DWC_EQOS_NUM_TXQ == 1.
> -	 */
> -	mtl_tx_op |= MTL_OP_MODE_TXQEN | MTL_OP_MODE_TQS_MASK;
> -	writel(mtl_tx_op, ioaddr +  MTL_CHAN_TX_OP_MODE(channel));
> +	unsigned int rqs = fifosz / 256 - 1;
> +	u32 mtl_rx_op, mtl_rx_int;
>  
>  	mtl_rx_op = readl(ioaddr + MTL_CHAN_RX_OP_MODE(channel));
>  
> -	if (rxmode == SF_DMA_MODE) {
> +	if (mode == SF_DMA_MODE) {
>  		pr_debug("GMAC: enable RX store and forward mode\n");
>  		mtl_rx_op |= MTL_OP_MODE_RSF;
>  	} else {
> -		pr_debug("GMAC: disable RX SF mode (threshold %d)\n", rxmode);
> +		pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
>  		mtl_rx_op &= ~MTL_OP_MODE_RSF;
>  		mtl_rx_op &= MTL_OP_MODE_RTC_MASK;
> -		if (rxmode <= 32)
> +		if (mode <= 32)
>  			mtl_rx_op |= MTL_OP_MODE_RTC_32;
> -		else if (rxmode <= 64)
> +		else if (mode <= 64)
>  			mtl_rx_op |= MTL_OP_MODE_RTC_64;
> -		else if (rxmode <= 96)
> +		else if (mode <= 96)
>  			mtl_rx_op |= MTL_OP_MODE_RTC_96;
>  		else
>  			mtl_rx_op |= MTL_OP_MODE_RTC_128;
> @@ -255,7 +211,7 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
>  	mtl_rx_op |= rqs << MTL_OP_MODE_RQS_SHIFT;
>  
>  	/* enable flow control only if each channel gets 4 KiB or more FIFO */
> -	if (rxfifosz >= 4096) {
> +	if (fifosz >= 4096) {
>  		unsigned int rfd, rfa;
>  
>  		mtl_rx_op |= MTL_OP_MODE_EHFC;
> @@ -266,7 +222,7 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
>  		 * Set Threshold for Deactivating Flow Control to min 1 frame,
>  		 * i.e. 1500 bytes.
>  		 */
> -		switch (rxfifosz) {
> +		switch (fifosz) {
>  		case 4096:
>  			/* This violates the above formula because of FIFO size
>  			 * limit therefore overflow may occur in spite of this.
> @@ -306,11 +262,49 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
>  	       ioaddr + MTL_CHAN_INT_CTRL(channel));
>  }
>  
> -static void dwmac4_dma_operation_mode(void __iomem *ioaddr, int txmode,
> -				      int rxmode, int rxfifosz)
> +static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode,
> +				       u32 channel)
>  {
> -	/* Only Channel 0 is actually configured and used */
> -	dwmac4_dma_chan_op_mode(ioaddr, txmode, rxmode, 0, rxfifosz);
> +	u32 mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));
> +
> +	if (mode == SF_DMA_MODE) {
> +		pr_debug("GMAC: enable TX store and forward mode\n");
> +		/* Transmit COE type 2 cannot be done in cut-through mode. */
> +		mtl_tx_op |= MTL_OP_MODE_TSF;
> +	} else {
> +		pr_debug("GMAC: disabling TX SF (threshold %d)\n", mode);
> +		mtl_tx_op &= ~MTL_OP_MODE_TSF;
> +		mtl_tx_op &= MTL_OP_MODE_TTC_MASK;
> +		/* Set the transmit threshold */
> +		if (mode <= 32)
> +			mtl_tx_op |= MTL_OP_MODE_TTC_32;
> +		else if (mode <= 64)
> +			mtl_tx_op |= MTL_OP_MODE_TTC_64;
> +		else if (mode <= 96)
> +			mtl_tx_op |= MTL_OP_MODE_TTC_96;
> +		else if (mode <= 128)
> +			mtl_tx_op |= MTL_OP_MODE_TTC_128;
> +		else if (mode <= 192)
> +			mtl_tx_op |= MTL_OP_MODE_TTC_192;
> +		else if (mode <= 256)
> +			mtl_tx_op |= MTL_OP_MODE_TTC_256;
> +		else if (mode <= 384)
> +			mtl_tx_op |= MTL_OP_MODE_TTC_384;
> +		else
> +			mtl_tx_op |= MTL_OP_MODE_TTC_512;
> +	}
> +	/* For an IP with DWC_EQOS_NUM_TXQ == 1, the fields TXQEN and TQS are RO
> +	 * with reset values: TXQEN on, TQS == DWC_EQOS_TXFIFO_SIZE.
> +	 * For an IP with DWC_EQOS_NUM_TXQ > 1, the fields TXQEN and TQS are R/W
> +	 * with reset values: TXQEN off, TQS 256 bytes.
> +	 *
> +	 * Write the bits in both cases, since it will have no effect when RO.
> +	 * For DWC_EQOS_NUM_TXQ > 1, the top bits in MTL_OP_MODE_TQS_MASK might
> +	 * be RO, however, writing the whole TQS field will result in a value
> +	 * equal to DWC_EQOS_TXFIFO_SIZE, just like for DWC_EQOS_NUM_TXQ == 1.
> +	 */
> +	mtl_tx_op |= MTL_OP_MODE_TXQEN | MTL_OP_MODE_TQS_MASK;
> +	writel(mtl_tx_op, ioaddr +  MTL_CHAN_TX_OP_MODE(channel));
>  }
>  
>  static void dwmac4_get_hw_feature(void __iomem *ioaddr,
> @@ -387,7 +381,8 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
>  	.init = dwmac4_dma_init,
>  	.axi = dwmac4_dma_axi,
>  	.dump_regs = dwmac4_dump_dma_regs,
> -	.dma_mode = dwmac4_dma_operation_mode,
> +	.dma_rx_mode = dwmac4_dma_rx_chan_op_mode,
> +	.dma_tx_mode = dwmac4_dma_tx_chan_op_mode,
>  	.enable_dma_irq = dwmac4_enable_dma_irq,
>  	.disable_dma_irq = dwmac4_disable_dma_irq,
>  	.start_tx = dwmac4_dma_start_tx,
> @@ -409,7 +404,8 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
>  	.init = dwmac4_dma_init,
>  	.axi = dwmac4_dma_axi,
>  	.dump_regs = dwmac4_dump_dma_regs,
> -	.dma_mode = dwmac4_dma_operation_mode,
> +	.dma_rx_mode = dwmac4_dma_rx_chan_op_mode,
> +	.dma_tx_mode = dwmac4_dma_tx_chan_op_mode,
>  	.enable_dma_irq = dwmac410_enable_dma_irq,
>  	.disable_dma_irq = dwmac4_disable_dma_irq,
>  	.start_tx = dwmac4_dma_start_tx,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index ec363e1..c4e4a53 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1285,14 +1285,20 @@ static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
>   */
>  static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
>  {
> +	u32 rx_channels_count = priv->plat->rx_queues_to_use;
> +	u32 tx_channels_count = priv->plat->tx_queues_to_use;
>  	int rxfifosz = priv->plat->rx_fifo_size;
> +	u32 txmode = 0;
> +	u32 rxmode = 0;
> +	u32 chan = 0;
>  
>  	if (rxfifosz == 0)
>  		rxfifosz = priv->dma_cap.rx_fifo_size;
>  
> -	if (priv->plat->force_thresh_dma_mode)
> -		priv->hw->dma->dma_mode(priv->ioaddr, tc, tc, rxfifosz);
> -	else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) {
> +	if (priv->plat->force_thresh_dma_mode) {
> +		txmode = tc;
> +		rxmode = tc;
> +	} else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) {
>  		/*
>  		 * In case of GMAC, SF mode can be enabled
>  		 * to perform the TX COE in HW. This depends on:
> @@ -1300,12 +1306,26 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
>  		 * 2) There is no bugged Jumbo frame support
>  		 *    that needs to not insert csum in the TDES.
>  		 */
> -		priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE,
> -					rxfifosz);
> +		txmode = SF_DMA_MODE;
> +		rxmode = SF_DMA_MODE;
>  		priv->xstats.threshold = SF_DMA_MODE;
> -	} else
> -		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE,
> +	} else {
> +		txmode = tc;
> +		rxmode = SF_DMA_MODE;
> +	}
> +
> +	/* configure all channels */
> +	if (priv->synopsys_id >= DWMAC_CORE_4_00) {
> +		for (chan = 0; chan < rx_channels_count; chan++)
> +			priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan,
> +						   rxfifosz);
> +
> +		for (chan = 0; chan < tx_channels_count; chan++)
> +			priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan);
> +	} else {
> +		priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode,
>  					rxfifosz);
> +	}
>  }
>  
>  /**
> @@ -1444,6 +1464,34 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
>  }
>  
>  /**
> + *  stmmac_set_dma_operation_mode - Set DMA operation mode by channel
> + *  @priv: driver private structure
> + *  @txmode: TX operating mode
> + *  @rxmode: RX operating mode
> + *  @chan: channel index
> + *  Description: it is used for configuring of the DMA operation mode in
> + *  runtime in order to program the tx/rx DMA thresholds or Store-And-Forward
> + *  mode.
> + */
> +static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode,
> +					  u32 rxmode, u32 chan)
> +{
> +	int rxfifosz = priv->plat->rx_fifo_size;
> +
> +	if (rxfifosz == 0)
> +		rxfifosz = priv->dma_cap.rx_fifo_size;
> +
> +	if (priv->synopsys_id >= DWMAC_CORE_4_00) {
> +		priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan,
> +					   rxfifosz);
> +		priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan);
> +	} else {
> +		priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode,
> +					rxfifosz);
> +	}
> +}
> +
> +/**
>   * stmmac_dma_interrupt - DMA ISR
>   * @priv: driver private structure
>   * Description: this is the DMA ISR. It is called by the main ISR.
> @@ -1452,11 +1500,8 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
>   */
>  static void stmmac_dma_interrupt(struct stmmac_priv *priv)
>  {
> +	u32 chan = STMMAC_CHAN0;
>  	int status;
> -	int rxfifosz = priv->plat->rx_fifo_size;
> -
> -	if (rxfifosz == 0)
> -		rxfifosz = priv->dma_cap.rx_fifo_size;
>  
>  	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
>  	if (likely((status & handle_rx)) || (status & handle_tx)) {
> @@ -1471,11 +1516,12 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
>  		    (tc <= 256)) {
>  			tc += 64;
>  			if (priv->plat->force_thresh_dma_mode)
> -				priv->hw->dma->dma_mode(priv->ioaddr, tc, tc,
> -							rxfifosz);
> +				stmmac_set_dma_operation_mode(priv->ioaddr,
> +							      tc, tc, chan);
>  			else
> -				priv->hw->dma->dma_mode(priv->ioaddr, tc,
> -							SF_DMA_MODE, rxfifosz);
> +				stmmac_set_dma_operation_mode(priv->ioaddr, tc,
> +							     SF_DMA_MODE, chan);
> +
>  			priv->xstats.threshold = tc;
>  		}
>  	} else if (unlikely(status == tx_hard_error))
> @@ -1749,6 +1795,9 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
>  	/* Enable MAC RX Queues */
>  	if (rx_queues_count > 1 && priv->hw->mac->rx_queue_enable)
>  		stmmac_mac_enable_rx_queues(priv);
> +
> +	/* Set the HW DMA mode and the COE */
> +	stmmac_dma_operation_mode(priv);
>  }
>  
>  /**
> @@ -1812,9 +1861,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
>  	else
>  		stmmac_set_mac(priv->ioaddr, true);
>  
> -	/* Set the HW DMA mode and the COE */
> -	stmmac_dma_operation_mode(priv);
> -
>  	stmmac_mmc_setup(priv);
>  
>  	if (init_ptp) {
> 

Starting with this patch, the stmmac-based network adapters of the Intel
Quark SoC stop working. I'm getting an IP via DHCP, I can ping, but TCP
connections can no longer be established.

Moving on a few patches (didn't bisect the exact one yet), the TX
watchdog starts to fire, and DHCP fails completely. And if I go to
current master in Linus tree (reverting an unrelated boot regression), I
even get a crash in stmmac_xmit.

Here are some details about the hw from dma_cap POV, if this helps:

==============================
        DMA HW features
==============================
        10/100 Mbps: Y
        1000 Mbps: N
        Half duplex: Y
        Hash Filter: Y
        Multiple MAC address registers: N
        PCS (TBI/SGMII/RTBI PHY interfaces): N
        SMA (MDIO) Interface: Y
        PMT Remote wake up: N
        PMT Magic Frame: N
        RMON module: Y
        IEEE 1588-2002 Time Stamp: N
        IEEE 1588-2008 Advanced Time Stamp: Y
        802.3az - Energy-Efficient Ethernet (EEE): N
        AV features: N
        Checksum Offload in TX: Y
        IP Checksum Offload (type1) in RX: N
        IP Checksum Offload (type2) in RX: Y
        RXFIFO > 2048bytes: Y
        Number of Additional RX channel: 0
        Number of Additional TX channel: 0
        Enhanced descriptors: Y

Given the number of different failure modes, my feeling is that there
are multiple regressions coming with these patches...

I've tested on the IOT2000 board, but I suspect the Galileo Gen2 will be
affected equally. If you don't have access to any such device, let me
know what I can debug for you.

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08  6:56   ` Jan Kiszka
@ 2017-05-08  9:36     ` Andy Shevchenko
  2017-05-08  9:54       ` Joao Pinto
  0 siblings, 1 reply; 23+ messages in thread
From: Andy Shevchenko @ 2017-05-08  9:36 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Joao Pinto, David S. Miller, Giuseppe CAVALLARO,
	Alexandre TORGUE, netdev, Linux Kernel Mailing List

On Mon, May 8, 2017 at 9:56 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 2017-03-15 12:04, Joao Pinto wrote:
>> This patch prepares DMA Operation Mode configuration for multiple queues.
>> The work consisted on breaking the DMA operation Mode configuration function
>> into RX and TX scope and adapting its mechanism in stmmac_main.

> Starting with this patch, the stmmac-based network adapters of the Intel
> Quark SoC stop working. I'm getting an IP via DHCP, I can ping, but TCP
> connections can no longer be established.
>
> Moving on a few patches (didn't bisect the exact one yet), the TX
> watchdog starts to fire, and DHCP fails completely. And if I go to
> current master in Linus tree (reverting an unrelated boot regression), I
> even get a crash in stmmac_xmit.
>
> Here are some details about the hw from dma_cap POV, if this helps:
>
> ==============================
>         DMA HW features
> ==============================
>         10/100 Mbps: Y
>         1000 Mbps: N
>         Half duplex: Y
>         Hash Filter: Y
>         Multiple MAC address registers: N
>         PCS (TBI/SGMII/RTBI PHY interfaces): N
>         SMA (MDIO) Interface: Y
>         PMT Remote wake up: N
>         PMT Magic Frame: N
>         RMON module: Y
>         IEEE 1588-2002 Time Stamp: N
>         IEEE 1588-2008 Advanced Time Stamp: Y
>         802.3az - Energy-Efficient Ethernet (EEE): N
>         AV features: N
>         Checksum Offload in TX: Y
>         IP Checksum Offload (type1) in RX: N
>         IP Checksum Offload (type2) in RX: Y
>         RXFIFO > 2048bytes: Y
>         Number of Additional RX channel: 0
>         Number of Additional TX channel: 0
>         Enhanced descriptors: Y
>
> Given the number of different failure modes, my feeling is that there
> are multiple regressions coming with these patches...
>
> I've tested on the IOT2000 board, but I suspect the Galileo Gen2 will be
> affected equally. If you don't have access to any such device, let me
> know what I can debug for you.

JFYI: With today's linux-next when _kexec:ed_ kernel boots I tried and
got the following:


# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferre[  130.403995] random: fast init done
d_lft forever
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
   link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
   link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
4: sit0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
   link/sit 0.0.0.0 brd 0.0.0.0
# udhcpc -i eth0
udhcpc: started, v1.26.2
[  140.825131] stmmaceth 0000:00:14.6 eth0: device MAC address 98:4f:ee:05:ac:47
[  140.834304] Generic PHY stmmac-a6:01: attached PHY driver [Generic
PHY] (mii_bus:phy_addr=stmmac-a6:01, irq=-1)
[  140.930871] stmmaceth 0000:00:14.6 eth0: IEEE 1588-2008 Advanced
Timestamp supported
[  140.941109] stmmaceth 0000:00:14.6 eth0: registered PTP clock
[  140.953626] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
udhcpc: sending discover
[  142.979557] stmmaceth 0000:00:14.6 eth0: Link is Up - 100Mbps/Full
- flow control off
[  142.988756] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[  142.998810] BUG: unable to handle kernel NULL pointer dereference at   (null)
[  143.006193] IP: stmmac_xmit+0xf1/0x1080
[  143.010168] *pde = 00000000
[  143.010177]
[  143.014762] Oops: 0002 [#1]
[  143.017672] Modules linked in: at24 nvmem_core pwm_pca9685
[  143.023338] CPU: 0 PID: 0 Comm: swapper Not tainted 4.11.0-next-20170508+ #2
[  143.030539] task: c8533580 task.stack: c852c000
[  143.035237] EIP: stmmac_xmit+0xf1/0x1080
[  143.039302] EFLAGS: 00010216 CPU: 0
[  143.042915] EAX: 00000000 EBX: 00000050 ECX: 00000000 EDX: ceb6a0c0
[  143.049326] ESI: 00000000 EDI: cdd16000 EBP: cdc25d70 ESP: cdc25d20
[  143.055735]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[  143.061271] CR0: 80050033 CR2: 00000000 CR3: 0eb5c000 CR4: 00100010
[  143.067671] Call Trace:
[  143.070238]  <SOFTIRQ>
[  143.072763]  dev_hard_start_xmit+0x7c/0x1a0
[  143.077120]  sch_direct_xmit+0xf0/0x120
[  143.081130]  __dev_queue_xmit+0x181/0x430
[  143.085311]  ? eth_commit_mac_addr_change+0x20/0x20
[  143.090362]  dev_queue_xmit+0xa/0x10
[  143.094100]  neigh_resolve_output+0xdb/0x190
[  143.098561]  ip6_finish_output2+0x184/0x500
[  143.102945]  ip6_finish_output+0x91/0xe0
[  143.107057]  ? ip6_finish_output+0x91/0xe0
[  143.111338]  ip6_output+0x36/0x110
[  143.114924]  ? ip6_fragment+0xb00/0xb00
[  143.118935]  mld_sendpack+0x191/0x2b0
[  143.122769]  ? mld_newpack+0xda/0x180
[  143.126598]  ? ipv6_icmp_sysctl_init+0x30/0x30
[  143.131224]  mld_ifc_timer_expire+0x158/0x240
[  143.135756]  ? find_next_bit+0xa/0x10
[  143.139584]  ? mld_dad_timer_expire+0x50/0x50
[  143.144112]  call_timer_fn+0x2a/0xf0
[  143.147862]  ? mld_dad_timer_expire+0x50/0x50
[  143.152395]  run_timer_softirq+0x158/0x300
[  143.156668]  ? file_free_rcu+0x1e/0x30
[  143.160589]  __do_softirq+0xc4/0x200
[  143.164341]  ? __hrtimer_tasklet_trampoline+0x30/0x30
[  143.169575]  do_softirq_own_stack+0x1e/0x30
[  143.173902]  </SOFTIRQ>
[  143.176502]  irq_exit+0x95/0xa0
[  143.179812]  smp_apic_timer_interrupt+0x31/0x40
[  143.184530]  apic_timer_interrupt+0x32/0x40
[  143.188889] EIP: default_idle+0xc/0x70
[  143.192774] EFLAGS: 00000246 CPU: 0
[  143.196386] EAX: 00000000 EBX: 00000000 ECX: 00000001 EDX: 00000000
[  143.202795] ESI: 00000000 EDI: c8533580 EBP: c852df54 ESP: c852df4c
[  143.209205]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[  143.214780]  arch_cpu_idle+0x9/0x10
[  143.218446]  default_idle_call+0x17/0x30
[  143.222551]  do_idle+0xed/0x130
[  143.225873]  cpu_startup_entry+0x15/0x20
[  143.229965]  rest_init+0x5c/0x60
[  143.233370]  start_kernel+0x313/0x318
[  143.237221]  i386_start_kernel+0x98/0x9c
[  143.241315]  startup_32_smp+0x16b/0x16d
[  143.245289] Code: 84 45 06 00 00 c1 e2 05 03 94 c7 9c 09 00 00 89
55 b0 8b 45 c8 8b 75 bc 8b 55 d8 8d 1c 80 89
75 e4 c1 e3 03 8b 84 1f a4 09 00 00 <89> 14 b0 8b 87 40 0d 00 00 8b 40
24 85 c0 89 45 b8 0f 85 68 02
[  143.264746] EIP: stmmac_xmit+0xf1/0x1080 SS:ESP: 0068:cdc25d20
[  143.270727] CR2: 0000000000000000
[  143.274175] ---[ end trace 79da8ef70f8b98d7 ]---
[  143.278925] Kernel panic - not syncing: Fatal exception in interrupt
[  143.285433] Kernel Offset: 0x6a00000 from 0xc1000000 (relocation
range: 0xc0000000-0xd05effff)
[  143.294268] ---[ end Kernel panic - not syncing: Fatal exception in interrupt


-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08  9:36     ` Andy Shevchenko
@ 2017-05-08  9:54       ` Joao Pinto
  2017-05-08 10:12         ` Andy Shevchenko
  0 siblings, 1 reply; 23+ messages in thread
From: Joao Pinto @ 2017-05-08  9:54 UTC (permalink / raw)
  To: Andy Shevchenko, Jan Kiszka
  Cc: Joao Pinto, David S. Miller, Giuseppe CAVALLARO,
	Alexandre TORGUE, netdev, Linux Kernel Mailing List

Hi Andy and Jan,

Às 10:36 AM de 5/8/2017, Andy Shevchenko escreveu:
> On Mon, May 8, 2017 at 9:56 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>> On 2017-03-15 12:04, Joao Pinto wrote:
>>> This patch prepares DMA Operation Mode configuration for multiple queues.
>>> The work consisted on breaking the DMA operation Mode configuration function
>>> into RX and TX scope and adapting its mechanism in stmmac_main.
> 
>> Starting with this patch, the stmmac-based network adapters of the Intel
>> Quark SoC stop working. I'm getting an IP via DHCP, I can ping, but TCP
>> connections can no longer be established.
>>
>> Moving on a few patches (didn't bisect the exact one yet), the TX
>> watchdog starts to fire, and DHCP fails completely. And if I go to
>> current master in Linus tree (reverting an unrelated boot regression), I
>> even get a crash in stmmac_xmit.
>>
>> Here are some details about the hw from dma_cap POV, if this helps:
>>
>> ==============================
>>         DMA HW features
>> ==============================
>>         10/100 Mbps: Y
>>         1000 Mbps: N
>>         Half duplex: Y
>>         Hash Filter: Y
>>         Multiple MAC address registers: N
>>         PCS (TBI/SGMII/RTBI PHY interfaces): N
>>         SMA (MDIO) Interface: Y
>>         PMT Remote wake up: N
>>         PMT Magic Frame: N
>>         RMON module: Y
>>         IEEE 1588-2002 Time Stamp: N
>>         IEEE 1588-2008 Advanced Time Stamp: Y
>>         802.3az - Energy-Efficient Ethernet (EEE): N
>>         AV features: N
>>         Checksum Offload in TX: Y
>>         IP Checksum Offload (type1) in RX: N
>>         IP Checksum Offload (type2) in RX: Y
>>         RXFIFO > 2048bytes: Y
>>         Number of Additional RX channel: 0
>>         Number of Additional TX channel: 0
>>         Enhanced descriptors: Y
>>
>> Given the number of different failure modes, my feeling is that there
>> are multiple regressions coming with these patches...
>>
>> I've tested on the IOT2000 board, but I suspect the Galileo Gen2 will be
>> affected equally. If you don't have access to any such device, let me
>> know what I can debug for you.
> 
> JFYI: With today's linux-next when _kexec:ed_ kernel boots I tried and
> got the following:
> 
> 
> # ip a s
> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
>    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
>    inet 127.0.0.1/8 scope host lo
>       valid_lft forever preferred_lft forever
>    inet6 ::1/128 scope host
>       valid_lft forever preferre[  130.403995] random: fast init done
> d_lft forever
> 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
>    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
> 3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
>    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
> 4: sit0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
>    link/sit 0.0.0.0 brd 0.0.0.0
> # udhcpc -i eth0
> udhcpc: started, v1.26.2
> [  140.825131] stmmaceth 0000:00:14.6 eth0: device MAC address 98:4f:ee:05:ac:47
> [  140.834304] Generic PHY stmmac-a6:01: attached PHY driver [Generic
> PHY] (mii_bus:phy_addr=stmmac-a6:01, irq=-1)
> [  140.930871] stmmaceth 0000:00:14.6 eth0: IEEE 1588-2008 Advanced
> Timestamp supported
> [  140.941109] stmmaceth 0000:00:14.6 eth0: registered PTP clock
> [  140.953626] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
> udhcpc: sending discover
> [  142.979557] stmmaceth 0000:00:14.6 eth0: Link is Up - 100Mbps/Full
> - flow control off
> [  142.988756] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
> [  142.998810] BUG: unable to handle kernel NULL pointer dereference at   (null)
> [  143.006193] IP: stmmac_xmit+0xf1/0x1080
> [  143.010168] *pde = 00000000
> [  143.010177]
> [  143.014762] Oops: 0002 [#1]
> [  143.017672] Modules linked in: at24 nvmem_core pwm_pca9685
> [  143.023338] CPU: 0 PID: 0 Comm: swapper Not tainted 4.11.0-next-20170508+ #2
> [  143.030539] task: c8533580 task.stack: c852c000
> [  143.035237] EIP: stmmac_xmit+0xf1/0x1080
> [  143.039302] EFLAGS: 00010216 CPU: 0
> [  143.042915] EAX: 00000000 EBX: 00000050 ECX: 00000000 EDX: ceb6a0c0
> [  143.049326] ESI: 00000000 EDI: cdd16000 EBP: cdc25d70 ESP: cdc25d20
> [  143.055735]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
> [  143.061271] CR0: 80050033 CR2: 00000000 CR3: 0eb5c000 CR4: 00100010
> [  143.067671] Call Trace:
> [  143.070238]  <SOFTIRQ>
> [  143.072763]  dev_hard_start_xmit+0x7c/0x1a0
> [  143.077120]  sch_direct_xmit+0xf0/0x120
> [  143.081130]  __dev_queue_xmit+0x181/0x430
> [  143.085311]  ? eth_commit_mac_addr_change+0x20/0x20
> [  143.090362]  dev_queue_xmit+0xa/0x10
> [  143.094100]  neigh_resolve_output+0xdb/0x190
> [  143.098561]  ip6_finish_output2+0x184/0x500
> [  143.102945]  ip6_finish_output+0x91/0xe0
> [  143.107057]  ? ip6_finish_output+0x91/0xe0
> [  143.111338]  ip6_output+0x36/0x110
> [  143.114924]  ? ip6_fragment+0xb00/0xb00
> [  143.118935]  mld_sendpack+0x191/0x2b0
> [  143.122769]  ? mld_newpack+0xda/0x180
> [  143.126598]  ? ipv6_icmp_sysctl_init+0x30/0x30
> [  143.131224]  mld_ifc_timer_expire+0x158/0x240
> [  143.135756]  ? find_next_bit+0xa/0x10
> [  143.139584]  ? mld_dad_timer_expire+0x50/0x50
> [  143.144112]  call_timer_fn+0x2a/0xf0
> [  143.147862]  ? mld_dad_timer_expire+0x50/0x50
> [  143.152395]  run_timer_softirq+0x158/0x300
> [  143.156668]  ? file_free_rcu+0x1e/0x30
> [  143.160589]  __do_softirq+0xc4/0x200
> [  143.164341]  ? __hrtimer_tasklet_trampoline+0x30/0x30
> [  143.169575]  do_softirq_own_stack+0x1e/0x30
> [  143.173902]  </SOFTIRQ>
> [  143.176502]  irq_exit+0x95/0xa0
> [  143.179812]  smp_apic_timer_interrupt+0x31/0x40
> [  143.184530]  apic_timer_interrupt+0x32/0x40
> [  143.188889] EIP: default_idle+0xc/0x70
> [  143.192774] EFLAGS: 00000246 CPU: 0
> [  143.196386] EAX: 00000000 EBX: 00000000 ECX: 00000001 EDX: 00000000
> [  143.202795] ESI: 00000000 EDI: c8533580 EBP: c852df54 ESP: c852df4c
> [  143.209205]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
> [  143.214780]  arch_cpu_idle+0x9/0x10
> [  143.218446]  default_idle_call+0x17/0x30
> [  143.222551]  do_idle+0xed/0x130
> [  143.225873]  cpu_startup_entry+0x15/0x20
> [  143.229965]  rest_init+0x5c/0x60
> [  143.233370]  start_kernel+0x313/0x318
> [  143.237221]  i386_start_kernel+0x98/0x9c
> [  143.241315]  startup_32_smp+0x16b/0x16d
> [  143.245289] Code: 84 45 06 00 00 c1 e2 05 03 94 c7 9c 09 00 00 89
> 55 b0 8b 45 c8 8b 75 bc 8b 55 d8 8d 1c 80 89
> 75 e4 c1 e3 03 8b 84 1f a4 09 00 00 <89> 14 b0 8b 87 40 0d 00 00 8b 40
> 24 85 c0 89 45 b8 0f 85 68 02
> [  143.264746] EIP: stmmac_xmit+0xf1/0x1080 SS:ESP: 0068:cdc25d20
> [  143.270727] CR2: 0000000000000000
> [  143.274175] ---[ end trace 79da8ef70f8b98d7 ]---
> [  143.278925] Kernel panic - not syncing: Fatal exception in interrupt
> [  143.285433] Kernel Offset: 0x6a00000 from 0xc1000000 (relocation
> range: 0xc0000000-0xd05effff)
> [  143.294268] ---[ end Kernel panic - not syncing: Fatal exception in interrupt
> 
> 

Are you using the same version of Ethernet IP, 10/100?
Could you please verify if the crash you are experiencing is this place?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c#n2956

I would say that for rather old IPs, the napi is not capable of giving a valid
queue number. Could you please print the queue index returned by this line?

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c#n2948

Thank you.

Joao Pinto

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08  9:54       ` Joao Pinto
@ 2017-05-08 10:12         ` Andy Shevchenko
  2017-05-08 10:42           ` Joao Pinto
  0 siblings, 1 reply; 23+ messages in thread
From: Andy Shevchenko @ 2017-05-08 10:12 UTC (permalink / raw)
  To: Joao Pinto
  Cc: Jan Kiszka, David S. Miller, Giuseppe CAVALLARO,
	Alexandre TORGUE, netdev, Linux Kernel Mailing List

On Mon, May 8, 2017 at 12:54 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
> Hi Andy and Jan,
>
> Às 10:36 AM de 5/8/2017, Andy Shevchenko escreveu:
>> On Mon, May 8, 2017 at 9:56 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>> On 2017-03-15 12:04, Joao Pinto wrote:
>>>> This patch prepares DMA Operation Mode configuration for multiple queues.
>>>> The work consisted on breaking the DMA operation Mode configuration function
>>>> into RX and TX scope and adapting its mechanism in stmmac_main.
>>
>>> Starting with this patch, the stmmac-based network adapters of the Intel
>>> Quark SoC stop working. I'm getting an IP via DHCP, I can ping, but TCP
>>> connections can no longer be established.

>> JFYI: With today's linux-next when _kexec:ed_ kernel boots I tried and
>> got the following:
>>
>>
>> # ip a s
>> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
>>    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
>>    inet 127.0.0.1/8 scope host lo
>>       valid_lft forever preferred_lft forever
>>    inet6 ::1/128 scope host
>>       valid_lft forever preferre[  130.403995] random: fast init done
>> d_lft forever
>> 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
>>    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
>> 3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
>>    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
>> 4: sit0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
>>    link/sit 0.0.0.0 brd 0.0.0.0
>> # udhcpc -i eth0
>> udhcpc: started, v1.26.2
>> [  140.825131] stmmaceth 0000:00:14.6 eth0: device MAC address 98:4f:ee:05:ac:47
>> [  140.834304] Generic PHY stmmac-a6:01: attached PHY driver [Generic
>> PHY] (mii_bus:phy_addr=stmmac-a6:01, irq=-1)
>> [  140.930871] stmmaceth 0000:00:14.6 eth0: IEEE 1588-2008 Advanced
>> Timestamp supported
>> [  140.941109] stmmaceth 0000:00:14.6 eth0: registered PTP clock
>> [  140.953626] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
>> udhcpc: sending discover
>> [  142.979557] stmmaceth 0000:00:14.6 eth0: Link is Up - 100Mbps/Full
>> - flow control off
>> [  142.988756] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
>> [  142.998810] BUG: unable to handle kernel NULL pointer dereference at   (null)
>> [  143.006193] IP: stmmac_xmit+0xf1/0x1080
>> [  143.010168] *pde = 00000000
>> [  143.010177]
>> [  143.014762] Oops: 0002 [#1]
>> [  143.017672] Modules linked in: at24 nvmem_core pwm_pca9685
>> [  143.023338] CPU: 0 PID: 0 Comm: swapper Not tainted 4.11.0-next-20170508+ #2
>> [  143.030539] task: c8533580 task.stack: c852c000
>> [  143.035237] EIP: stmmac_xmit+0xf1/0x1080
>> [  143.039302] EFLAGS: 00010216 CPU: 0
>> [  143.042915] EAX: 00000000 EBX: 00000050 ECX: 00000000 EDX: ceb6a0c0
>> [  143.049326] ESI: 00000000 EDI: cdd16000 EBP: cdc25d70 ESP: cdc25d20
>> [  143.055735]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
>> [  143.061271] CR0: 80050033 CR2: 00000000 CR3: 0eb5c000 CR4: 00100010
>> [  143.067671] Call Trace:
>> [  143.070238]  <SOFTIRQ>
>> [  143.072763]  dev_hard_start_xmit+0x7c/0x1a0
>> [  143.077120]  sch_direct_xmit+0xf0/0x120
>> [  143.081130]  __dev_queue_xmit+0x181/0x430
>> [  143.085311]  ? eth_commit_mac_addr_change+0x20/0x20
>> [  143.090362]  dev_queue_xmit+0xa/0x10
>> [  143.094100]  neigh_resolve_output+0xdb/0x190
>> [  143.098561]  ip6_finish_output2+0x184/0x500
>> [  143.102945]  ip6_finish_output+0x91/0xe0
>> [  143.107057]  ? ip6_finish_output+0x91/0xe0
>> [  143.111338]  ip6_output+0x36/0x110
>> [  143.114924]  ? ip6_fragment+0xb00/0xb00
>> [  143.118935]  mld_sendpack+0x191/0x2b0
>> [  143.122769]  ? mld_newpack+0xda/0x180
>> [  143.126598]  ? ipv6_icmp_sysctl_init+0x30/0x30
>> [  143.131224]  mld_ifc_timer_expire+0x158/0x240
>> [  143.135756]  ? find_next_bit+0xa/0x10
>> [  143.139584]  ? mld_dad_timer_expire+0x50/0x50
>> [  143.144112]  call_timer_fn+0x2a/0xf0
>> [  143.147862]  ? mld_dad_timer_expire+0x50/0x50
>> [  143.152395]  run_timer_softirq+0x158/0x300
>> [  143.156668]  ? file_free_rcu+0x1e/0x30
>> [  143.160589]  __do_softirq+0xc4/0x200
>> [  143.164341]  ? __hrtimer_tasklet_trampoline+0x30/0x30
>> [  143.169575]  do_softirq_own_stack+0x1e/0x30
>> [  143.173902]  </SOFTIRQ>
>> [  143.176502]  irq_exit+0x95/0xa0
>> [  143.179812]  smp_apic_timer_interrupt+0x31/0x40
>> [  143.184530]  apic_timer_interrupt+0x32/0x40
>> [  143.188889] EIP: default_idle+0xc/0x70
>> [  143.192774] EFLAGS: 00000246 CPU: 0
>> [  143.196386] EAX: 00000000 EBX: 00000000 ECX: 00000001 EDX: 00000000
>> [  143.202795] ESI: 00000000 EDI: c8533580 EBP: c852df54 ESP: c852df4c
>> [  143.209205]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
>> [  143.214780]  arch_cpu_idle+0x9/0x10
>> [  143.218446]  default_idle_call+0x17/0x30
>> [  143.222551]  do_idle+0xed/0x130
>> [  143.225873]  cpu_startup_entry+0x15/0x20
>> [  143.229965]  rest_init+0x5c/0x60
>> [  143.233370]  start_kernel+0x313/0x318
>> [  143.237221]  i386_start_kernel+0x98/0x9c
>> [  143.241315]  startup_32_smp+0x16b/0x16d
>> [  143.245289] Code: 84 45 06 00 00 c1 e2 05 03 94 c7 9c 09 00 00 89
>> 55 b0 8b 45 c8 8b 75 bc 8b 55 d8 8d 1c 80 89
>> 75 e4 c1 e3 03 8b 84 1f a4 09 00 00 <89> 14 b0 8b 87 40 0d 00 00 8b 40
>> 24 85 c0 89 45 b8 0f 85 68 02
>> [  143.264746] EIP: stmmac_xmit+0xf1/0x1080 SS:ESP: 0068:cdc25d20
>> [  143.270727] CR2: 0000000000000000
>> [  143.274175] ---[ end trace 79da8ef70f8b98d7 ]---
>> [  143.278925] Kernel panic - not syncing: Fatal exception in interrupt
>> [  143.285433] Kernel Offset: 0x6a00000 from 0xc1000000 (relocation
>> range: 0xc0000000-0xd05effff)
>> [  143.294268] ---[ end Kernel panic - not syncing: Fatal exception in interrupt
>>
>>
>
> Are you using the same version of Ethernet IP, 10/100?

I'm running on Intel Galileo Gen2 board (v4.11 by the way works fine
with direct boot from SD card)

> Could you please verify if the crash you are experiencing is this place?
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c#n2956
>
> I would say that for rather old IPs, the napi is not capable of giving a valid
> queue number. Could you please print the queue index returned by this line?
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c#n2948

--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2953,7 +2953,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff
*skb, struct net_device *dev)
       unsigned int enh_desc;
       unsigned int des;

+       pr_info("%s <<< 1: priv %p, queue: %u\n", __func__, priv, queue);
       tx_q = &priv->tx_queue[queue];
+       pr_info("%s <<< 2: priv %p, queue: %u tx_q: %p\n", __func__,
priv, queue, tx_q);


[  101.591040] stmmac_xmit <<< 1: priv cdd1c4c0, queue: 7
[  101.596377] stmmac_xmit <<< 2: priv cdd1c4c0, queue: 7 tx_q: cdd1caac


Also noticed warning that have to be addressed:

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2504:49: warning:
incorrect type in argument 1 (different address spaces)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2504:49:    expected
void [noderef] <asn:2>*ioaddr
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2504:49:    got
struct mac_device_info *hw

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function
‘init_dma_rx_desc_rings’:
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:1274:15: warning:
comparison of
unsigned expression >= 0 is always true [-Wtype-limits]
 while (queue >= 0) {
              ^~

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08 10:12         ` Andy Shevchenko
@ 2017-05-08 10:42           ` Joao Pinto
  2017-05-08 11:34             ` Andy Shevchenko
  0 siblings, 1 reply; 23+ messages in thread
From: Joao Pinto @ 2017-05-08 10:42 UTC (permalink / raw)
  To: Andy Shevchenko, Joao Pinto
  Cc: Jan Kiszka, David S. Miller, Giuseppe CAVALLARO,
	Alexandre TORGUE, netdev, Linux Kernel Mailing List

Às 11:12 AM de 5/8/2017, Andy Shevchenko escreveu:
> On Mon, May 8, 2017 at 12:54 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>> Hi Andy and Jan,
>>
>> Às 10:36 AM de 5/8/2017, Andy Shevchenko escreveu:
>>> On Mon, May 8, 2017 at 9:56 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>>> On 2017-03-15 12:04, Joao Pinto wrote:
>>>>> This patch prepares DMA Operation Mode configuration for multiple queues.
>>>>> The work consisted on breaking the DMA operation Mode configuration function
>>>>> into RX and TX scope and adapting its mechanism in stmmac_main.
>>>
>>>> Starting with this patch, the stmmac-based network adapters of the Intel
>>>> Quark SoC stop working. I'm getting an IP via DHCP, I can ping, but TCP
>>>> connections can no longer be established.
> 
>>> JFYI: With today's linux-next when _kexec:ed_ kernel boots I tried and
>>> got the following:
>>>

snip (...)

>>>
>>>
>>
>> Are you using the same version of Ethernet IP, 10/100?
> 
> I'm running on Intel Galileo Gen2 board (v4.11 by the way works fine
> with direct boot from SD card)
> 
>> Could you please verify if the crash you are experiencing is this place?
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fmain.c-23n2956&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=UF269QZ9ExFRw1XXpgdvO2QeTCLEp-GquRe8OqZwRf0&s=yZu3uME5PK-3nJlxz-H-HfHh3Shjzg0je5If_jSXVb4&e= 
>>
>> I would say that for rather old IPs, the napi is not capable of giving a valid
>> queue number. Could you please print the queue index returned by this line?
>>
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fmain.c-23n2948&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=UF269QZ9ExFRw1XXpgdvO2QeTCLEp-GquRe8OqZwRf0&s=p_TgHODJum23I2N4AldR4oIaOPffSDpk9agmbRMQgoM&e= 
> 
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -2953,7 +2953,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff
> *skb, struct net_device *dev)
>        unsigned int enh_desc;
>        unsigned int des;
> 
> +       pr_info("%s <<< 1: priv %p, queue: %u\n", __func__, priv, queue);
>        tx_q = &priv->tx_queue[queue];
> +       pr_info("%s <<< 2: priv %p, queue: %u tx_q: %p\n", __func__,
> priv, queue, tx_q);
> 
> 
> [  101.591040] stmmac_xmit <<< 1: priv cdd1c4c0, queue: 7
> [  101.596377] stmmac_xmit <<< 2: priv cdd1c4c0, queue: 7 tx_q: cdd1caac
> 

I assume that the queue index is always 7 right? By return 7, the napi interface
'thinks' that your setup is using 8 TX queues which I assume it is not and thats
the problem causing your board to malfuntion.

Could you please check the values of the 'real' tx and rx queues count in this line?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c#n4107

For default they are =1, so napi should be assuming 1RX and 1TX, and so you
should be getting queue index =0 in reception and transmission.

In terms of reception, could you print the queue index that stmmac_poll is using
here:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c#n3468

> 
> Also noticed warning that have to be addressed:
> 
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2504:49: warning:
> incorrect type in argument 1 (different address spaces)
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2504:49:    expected
> void [noderef] <asn:2>*ioaddr
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2504:49:    got
> struct mac_device_info *hw

This one was well caught! Although it has no influence in your setup, since you
don't have this callback implemented, eQOS (>= 4.00) and 1000 cores will have
issues if using PCS. I can make a patch for this one.

> 
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function
> ‘init_dma_rx_desc_rings’:
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:1274:15: warning:
> comparison of
> unsigned expression >= 0 is always true [-Wtype-limits]
>  while (queue >= 0) {
>               ^~

This one I have in my agenda to improve it, I also talked about it with Dan
Carpenter about it.

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08 10:42           ` Joao Pinto
@ 2017-05-08 11:34             ` Andy Shevchenko
  2017-05-08 11:40               ` Joao Pinto
  0 siblings, 1 reply; 23+ messages in thread
From: Andy Shevchenko @ 2017-05-08 11:34 UTC (permalink / raw)
  To: Joao Pinto
  Cc: Jan Kiszka, David S. Miller, Giuseppe CAVALLARO,
	Alexandre TORGUE, netdev, Linux Kernel Mailing List

On Mon, May 8, 2017 at 1:42 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
> Às 11:12 AM de 5/8/2017, Andy Shevchenko escreveu:
>> On Mon, May 8, 2017 at 12:54 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>> Às 10:36 AM de 5/8/2017, Andy Shevchenko escreveu:

>>>> JFYI: With today's linux-next when _kexec:ed_ kernel boots I tried and
>>>> got the following:

>>> Are you using the same version of Ethernet IP, 10/100?
>>
>> I'm running on Intel Galileo Gen2 board (v4.11 by the way works fine
>> with direct boot from SD card)
>>
>>> Could you please verify if the crash you are experiencing is this place?
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fmain.c-23n2956&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=UF269QZ9ExFRw1XXpgdvO2QeTCLEp-GquRe8OqZwRf0&s=yZu3uME5PK-3nJlxz-H-HfHh3Shjzg0je5If_jSXVb4&e=
>>>
>>> I would say that for rather old IPs, the napi is not capable of giving a valid
>>> queue number. Could you please print the queue index returned by this line?
>>>
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fmain.c-23n2948&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=UF269QZ9ExFRw1XXpgdvO2QeTCLEp-GquRe8OqZwRf0&s=p_TgHODJum23I2N4AldR4oIaOPffSDpk9agmbRMQgoM&e=
>>
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -2953,7 +2953,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff
>> *skb, struct net_device *dev)
>>        unsigned int enh_desc;
>>        unsigned int des;
>>
>> +       pr_info("%s <<< 1: priv %p, queue: %u\n", __func__, priv, queue);
>>        tx_q = &priv->tx_queue[queue];
>> +       pr_info("%s <<< 2: priv %p, queue: %u tx_q: %p\n", __func__,
>> priv, queue, tx_q);
>>
>>
>> [  101.591040] stmmac_xmit <<< 1: priv cdd1c4c0, queue: 7
>> [  101.596377] stmmac_xmit <<< 2: priv cdd1c4c0, queue: 7 tx_q: cdd1caac

> I assume that the queue index is always 7 right? By return 7, the napi interface
> 'thinks' that your setup is using 8 TX queues which I assume it is not and thats
> the problem causing your board to malfuntion.
>
> Could you please check the values of the 'real' tx and rx queues count in this line?
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c#n4107
>
> For default they are =1, so napi should be assuming 1RX and 1TX, and so you
> should be getting queue index =0 in reception and transmission.
>
> In terms of reception, could you print the queue index that stmmac_poll is using
> here:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c#n3468

+       pr_info("%s <<< %u\n", __func__, rx_q->queue_index);
       work_done = stmmac_rx(priv, budget, rx_q->queue_index);
       if (work_done < budget) {
               napi_complete_done(napi, work_done);

       /* Configure real RX and TX queues */
       netif_set_real_num_rx_queues(ndev, priv->plat->rx_queues_to_use);
       netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
+       pr_info("%s <<< %hhu %hhu\n", __func__,
priv->plat->rx_queues_to_use, priv->plat->tx_queues_to_use);


[   44.374161] stmmac_dvr_probe <<< 0 0

[  109.014763] stmmac_xmit <<< 1: priv cdcea4c0, queue: 2
[  109.020099] stmmac_xmit <<< 2: priv cdcea4c0, queue: 2 tx_q: cdcea9e4

That's all, no poll activated.

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08 11:34             ` Andy Shevchenko
@ 2017-05-08 11:40               ` Joao Pinto
  2017-05-08 11:56                 ` Andy Shevchenko
  0 siblings, 1 reply; 23+ messages in thread
From: Joao Pinto @ 2017-05-08 11:40 UTC (permalink / raw)
  To: Andy Shevchenko, Joao Pinto
  Cc: Jan Kiszka, David S. Miller, Giuseppe CAVALLARO,
	Alexandre TORGUE, netdev, Linux Kernel Mailing List

Às 12:34 PM de 5/8/2017, Andy Shevchenko escreveu:
> On Mon, May 8, 2017 at 1:42 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>> Às 11:12 AM de 5/8/2017, Andy Shevchenko escreveu:
>>> On Mon, May 8, 2017 at 12:54 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>>> Às 10:36 AM de 5/8/2017, Andy Shevchenko escreveu:
> 
>>>>> JFYI: With today's linux-next when _kexec:ed_ kernel boots I tried and
>>>>> got the following:
> 
>>>> Are you using the same version of Ethernet IP, 10/100?
>>>
>>> I'm running on Intel Galileo Gen2 board (v4.11 by the way works fine
>>> with direct boot from SD card)
>>>
>>>> Could you please verify if the crash you are experiencing is this place?
>>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fmain.c-23n2956&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=UF269QZ9ExFRw1XXpgdvO2QeTCLEp-GquRe8OqZwRf0&s=yZu3uME5PK-3nJlxz-H-HfHh3Shjzg0je5If_jSXVb4&e=
>>>>
>>>> I would say that for rather old IPs, the napi is not capable of giving a valid
>>>> queue number. Could you please print the queue index returned by this line?
>>>>
>>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fmain.c-23n2948&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=UF269QZ9ExFRw1XXpgdvO2QeTCLEp-GquRe8OqZwRf0&s=p_TgHODJum23I2N4AldR4oIaOPffSDpk9agmbRMQgoM&e=
>>>
>>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> @@ -2953,7 +2953,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff
>>> *skb, struct net_device *dev)
>>>        unsigned int enh_desc;
>>>        unsigned int des;
>>>
>>> +       pr_info("%s <<< 1: priv %p, queue: %u\n", __func__, priv, queue);
>>>        tx_q = &priv->tx_queue[queue];
>>> +       pr_info("%s <<< 2: priv %p, queue: %u tx_q: %p\n", __func__,
>>> priv, queue, tx_q);
>>>
>>>
>>> [  101.591040] stmmac_xmit <<< 1: priv cdd1c4c0, queue: 7
>>> [  101.596377] stmmac_xmit <<< 2: priv cdd1c4c0, queue: 7 tx_q: cdd1caac
> 
>> I assume that the queue index is always 7 right? By return 7, the napi interface
>> 'thinks' that your setup is using 8 TX queues which I assume it is not and thats
>> the problem causing your board to malfuntion.
>>
>> Could you please check the values of the 'real' tx and rx queues count in this line?
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fmain.c-23n4107&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=6PN46fgWi1XTHkxFzV9wkYHPkKJWvkRC1OOlEhyKdcA&s=cyYmWeYuPwacYmVRzJbhRm3Krz6XNyHbxq8t7ZUi8Ec&e= 
>>
>> For default they are =1, so napi should be assuming 1RX and 1TX, and so you
>> should be getting queue index =0 in reception and transmission.
>>
>> In terms of reception, could you print the queue index that stmmac_poll is using
>> here:
>>
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fmain.c-23n3468&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=6PN46fgWi1XTHkxFzV9wkYHPkKJWvkRC1OOlEhyKdcA&s=Xli0e7Key3FA7Rve_opcwc6W7nd4khVX15wwoNpFHL4&e= 
> 
> +       pr_info("%s <<< %u\n", __func__, rx_q->queue_index);
>        work_done = stmmac_rx(priv, budget, rx_q->queue_index);
>        if (work_done < budget) {
>                napi_complete_done(napi, work_done);
> 
>        /* Configure real RX and TX queues */
>        netif_set_real_num_rx_queues(ndev, priv->plat->rx_queues_to_use);
>        netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
> +       pr_info("%s <<< %hhu %hhu\n", __func__,
> priv->plat->rx_queues_to_use, priv->plat->tx_queues_to_use);
> 
> 
> [   44.374161] stmmac_dvr_probe <<< 0 0
> 

Ok, so this is the cause of the problem. The driver is geting 0 for real RX and
TX queues.

Your setup uses standard DT parsing from stmmac_platform or a custom one?

If you are using stmmac_probe_config_dt():
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c#n363

You will find a function named stmmac_mtl_setup() being called:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c#n492

In this function, the number of RX and TX queues is being set to 1 by default.

Joao


> [  109.014763] stmmac_xmit <<< 1: priv cdcea4c0, queue: 2
> [  109.020099] stmmac_xmit <<< 2: priv cdcea4c0, queue: 2 tx_q: cdcea9e4
> 
> That's all, no poll activated.
> 

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08 11:40               ` Joao Pinto
@ 2017-05-08 11:56                 ` Andy Shevchenko
  2017-05-08 12:02                   ` Joao Pinto
  0 siblings, 1 reply; 23+ messages in thread
From: Andy Shevchenko @ 2017-05-08 11:56 UTC (permalink / raw)
  To: Joao Pinto
  Cc: Jan Kiszka, David S. Miller, Giuseppe CAVALLARO,
	Alexandre TORGUE, netdev, Linux Kernel Mailing List

On Mon, May 8, 2017 at 2:40 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
> Às 12:34 PM de 5/8/2017, Andy Shevchenko escreveu:
>> On Mon, May 8, 2017 at 1:42 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>> Às 11:12 AM de 5/8/2017, Andy Shevchenko escreveu:
>>>> On Mon, May 8, 2017 at 12:54 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>>>> Às 10:36 AM de 5/8/2017, Andy Shevchenko escreveu:

>>
>> [   44.374161] stmmac_dvr_probe <<< 0 0
>>
>
> Ok, so this is the cause of the problem. The driver is geting 0 for real RX and
> TX queues.
>
> Your setup uses standard DT parsing from stmmac_platform or a custom one?
>
> If you are using stmmac_probe_config_dt():
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c#n363
>
> You will find a function named stmmac_mtl_setup() being called:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c#n492
>
> In this function, the number of RX and TX queues is being set to 1 by default.

Ah-ha, now I know how it's happened.
You forget to update all setup() hooks in PCI bus driver :-)

I will prepare a fix.
Just tell me should I put Fixes tag or not? And if yes, what commit
should I refer to?

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08 11:56                 ` Andy Shevchenko
@ 2017-05-08 12:02                   ` Joao Pinto
  2017-05-08 12:36                     ` Jan Kiszka
  0 siblings, 1 reply; 23+ messages in thread
From: Joao Pinto @ 2017-05-08 12:02 UTC (permalink / raw)
  To: Andy Shevchenko, Joao Pinto
  Cc: Jan Kiszka, David S. Miller, Giuseppe CAVALLARO,
	Alexandre TORGUE, netdev, Linux Kernel Mailing List

Às 12:56 PM de 5/8/2017, Andy Shevchenko escreveu:
> On Mon, May 8, 2017 at 2:40 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>> Às 12:34 PM de 5/8/2017, Andy Shevchenko escreveu:
>>> On Mon, May 8, 2017 at 1:42 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>>> Às 11:12 AM de 5/8/2017, Andy Shevchenko escreveu:
>>>>> On Mon, May 8, 2017 at 12:54 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>>>>> Às 10:36 AM de 5/8/2017, Andy Shevchenko escreveu:
> 
>>>
>>> [   44.374161] stmmac_dvr_probe <<< 0 0
>>>
>>
>> Ok, so this is the cause of the problem. The driver is geting 0 for real RX and
>> TX queues.
>>
>> Your setup uses standard DT parsing from stmmac_platform or a custom one?
>>
>> If you are using stmmac_probe_config_dt():
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fplatform.c-23n363&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=fJQj7RiT2sksJYOAZ9VSJUDnxPR7RlE6Fw_cTV0_Mqc&s=KhdAPUtP0twDkibE89cLYs8JjnxEvBgav5uf08WL_e8&e= 
>>
>> You will find a function named stmmac_mtl_setup() being called:
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fplatform.c-23n492&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=fJQj7RiT2sksJYOAZ9VSJUDnxPR7RlE6Fw_cTV0_Mqc&s=rTxn0fwdudwq9XAquH60xNHN538KBQ6_n4wODdLoyA0&e= 
>>
>> In this function, the number of RX and TX queues is being set to 1 by default.
> 
> Ah-ha, now I know how it's happened.
> You forget to update all setup() hooks in PCI bus driver :-)
> 
> I will prepare a fix.
> Just tell me should I put Fixes tag or not? And if yes, what commit
> should I refer to?
> 

Great, you can use this commit:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c?id=26d6851fd24ed5d88580d66b4c8384947d5ca29b

Thanks!

Joao

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

* Re: [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config for multiple queues
  2017-05-08 12:02                   ` Joao Pinto
@ 2017-05-08 12:36                     ` Jan Kiszka
  0 siblings, 0 replies; 23+ messages in thread
From: Jan Kiszka @ 2017-05-08 12:36 UTC (permalink / raw)
  To: Joao Pinto, Andy Shevchenko
  Cc: David S. Miller, Giuseppe CAVALLARO, Alexandre TORGUE, netdev,
	Linux Kernel Mailing List

On 2017-05-08 14:02, Joao Pinto wrote:
> Às 12:56 PM de 5/8/2017, Andy Shevchenko escreveu:
>> On Mon, May 8, 2017 at 2:40 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>> Às 12:34 PM de 5/8/2017, Andy Shevchenko escreveu:
>>>> On Mon, May 8, 2017 at 1:42 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>>>> Às 11:12 AM de 5/8/2017, Andy Shevchenko escreveu:
>>>>>> On Mon, May 8, 2017 at 12:54 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
>>>>>>> Às 10:36 AM de 5/8/2017, Andy Shevchenko escreveu:
>>
>>>>
>>>> [   44.374161] stmmac_dvr_probe <<< 0 0
>>>>
>>>
>>> Ok, so this is the cause of the problem. The driver is geting 0 for real RX and
>>> TX queues.
>>>
>>> Your setup uses standard DT parsing from stmmac_platform or a custom one?
>>>
>>> If you are using stmmac_probe_config_dt():
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fplatform.c-23n363&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=fJQj7RiT2sksJYOAZ9VSJUDnxPR7RlE6Fw_cTV0_Mqc&s=KhdAPUtP0twDkibE89cLYs8JjnxEvBgav5uf08WL_e8&e= 
>>>
>>> You will find a function named stmmac_mtl_setup() being called:
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_torvalds_linux.git_tree_drivers_net_ethernet_stmicro_stmmac_stmmac-5Fplatform.c-23n492&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=fJQj7RiT2sksJYOAZ9VSJUDnxPR7RlE6Fw_cTV0_Mqc&s=rTxn0fwdudwq9XAquH60xNHN538KBQ6_n4wODdLoyA0&e= 
>>>
>>> In this function, the number of RX and TX queues is being set to 1 by default.
>>
>> Ah-ha, now I know how it's happened.
>> You forget to update all setup() hooks in PCI bus driver :-)
>>
>> I will prepare a fix.
>> Just tell me should I put Fixes tag or not? And if yes, what commit
>> should I refer to?
>>
> 
> Great, you can use this commit:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c?id=26d6851fd24ed5d88580d66b4c8384947d5ca29b
> 
> Thanks!
> 
> Joao
> 

Perfect, looking forward to try out a fix. Thanks, folks!

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

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

end of thread, other threads:[~2017-05-08 12:36 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-15 11:04 [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations for multiple queues Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 01/11] net: stmmac: prepare dma op mode config " Joao Pinto
2017-05-08  6:56   ` Jan Kiszka
2017-05-08  9:36     ` Andy Shevchenko
2017-05-08  9:54       ` Joao Pinto
2017-05-08 10:12         ` Andy Shevchenko
2017-05-08 10:42           ` Joao Pinto
2017-05-08 11:34             ` Andy Shevchenko
2017-05-08 11:40               ` Joao Pinto
2017-05-08 11:56                 ` Andy Shevchenko
2017-05-08 12:02                   ` Joao Pinto
2017-05-08 12:36                     ` Jan Kiszka
2017-03-15 11:04 ` [PATCH v3 net-next 02/11] net: stmmac: enable/disable dma irq prepared " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 03/11] net: stmmac: rx/tx dma start/stop " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 04/11] net: stmmac: prepare stmmac_tx_err " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 05/11] net: stmmac: prepare dma interrupt treatment " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 06/11] net: stmmac: rx watchdog config prepared " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 07/11] net: stmmac: rx and tx ring length " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 08/11] net: stmmac: prepare rx/tx set tail function " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 09/11] net: stmmac: dma channel init prepared " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 10/11] net: stmmac: tso " Joao Pinto
2017-03-15 11:04 ` [PATCH v3 net-next 11/11] net: stmmac: stmmac interrupt treatment " Joao Pinto
2017-03-15 21:44 ` [PATCH v3 net-next 00/11] net: stmmac: prepare dma operations " David Miller

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.