Skip to contentSkip to conversation

add support for multiple queues/channels in stmmac

PATCH In review Joao Pinto 2 participants 7 messages Feb 16, 2017 – Feb 17, 2017

Subsystems (5)
lore
Share & tools
lore

Joao Pinto

author
#0 lore raw

v2 cover add support for multiple queues/channels in stmmac

This patch-set was built in order to be easy for a developer to have a clear view of what was done to add multiple queues/channels to stmmac. It shows a progressive work starting in an initial mac functions upgrade, followed by dma related functions upgrade and finally introcuding the multiple buffers.

Some of the functions had to be broken in RX and TX related, in order to enable separated treatment, since the number of RX queues can be different from the number of TX queues for example.

Each patch and the final patch-set were tested using a 4.21 EQOS IP Core.

Joao Pinto (3):
net: stmicro: prepare dwmac4 core for mtl
net: stmicro: prepare dwmac4 dma for mtl
net: stmicro: multiple buffer support

 Documentation/devicetree/bindings/net/stmmac.txt   |   11 +
 drivers/net/ethernet/stmicro/stmmac/chain_mode.c   |   44 +-
 drivers/net/ethernet/stmicro/stmmac/common.h       |   89 +-
 .../net/ethernet/stmicro/stmmac/dwmac1000_core.c   |    6 +-
 .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c    |   16 +-
 .../net/ethernet/stmicro/stmmac/dwmac100_core.c    |    3 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c |   19 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4.h       |   49 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  |  194 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c   |  297 ++-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h   |   25 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c   |   58 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h    |   15 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c    |   14 +-
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c    |   47 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |   47 +-
 .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   |   25 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 1961 ++++++++++++++------
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   33 +
 include/linux/stmmac.h                             |    8 +
 20 files changed, 2152 insertions(+), 809 deletions(-)
Signature · 1 line
2.9.3
author
#1 lore raw

PATCH v2 1/3 net: stmicro: prepare dwmac4 core for mtl

This patch adds the following features:

a) RX and TX scheduling algorithm configuration (can be configured in the Device Tree)
b) TX VLAN tag priority configuration (can be configured in the Device Tree)
c) RX VLAN tag priority routing configuration (can be configured in the Device Tree)
d) TX weight configuration (can be configured in the Device Tree)
e) RX queue to RX DMA channel mapping
f) RX queue enabling
g) MAC and individual queue related interrupt analysis
h) Flow Control configuration by queue

The number of RX and TX queues to use comes from the FEATURES register.

With this patch we get the core related operations ready for multiple queue/channel.

---
changes v1->v2:
- Kbuild test robot detected an unused variable (fixed)

 Documentation/devicetree/bindings/net/stmmac.txt   |  11 ++
 drivers/net/ethernet/stmicro/stmmac/common.h       |  29 ++-
 .../net/ethernet/stmicro/stmmac/dwmac1000_core.c   |   6 +-
 .../net/ethernet/stmicro/stmmac/dwmac100_core.c    |   3 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4.h       |  39 ++++-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  | 194 ++++++++++++++++++---
 .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   |  21 ++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 152 ++++++++++++++--
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |  33 ++++
 include/linux/stmmac.h                             |   8 +
 10 files changed, 445 insertions(+), 51 deletions(-)
Documentation/devicetree/bindings/net/stmmac.txt +11 -0
index d3bfc2b..9c5c135 100644
@@ -60,6 +60,17 @@ Optional properties:
 		 and MAC2MAC connection.
 - snps,tso: this enables the TSO feature otherwise it will be managed by
 		 MAC HW capability register. Only for GMAC4 and newer.
+- Tx MTL algorithm configuration: below the list of the available Tx algorithms:
+	- snps,tx-sched-wrr: WRR algorithm
+	- snps,tx-sched-wfq: WFQ algorithm (when DCB feature is selected)
+	- snps,tx-sched-dwrr: DWRR algorithm (when DCB feature is selected)
+	- snps,tx-sched-prio: Strict priority algorithm
+- Rx MTL algorithm configuration: below the list of the available Rx algorithms:
+	- snps,rx-sched-sp: Strict priority algorithm
+	- snps,rx-sched-wsp: Weighted strict priority algorithm
+- snps,tx-queue-weight: this is a vector to configure the TX queue weights
+- snps,rx-queue-prio: this is a vector to configure the RX queue priorities
+- snps,tx-queue-prio: this is a vector to configure the TX queue priorities
 - AXI BUS Mode parameters: below the list of all the parameters to program the
 			   AXI register inside the DMA module:
 	- snps,lpi_en: enable Low Power Interface
drivers/net/ethernet/stmicro/stmmac/common.h +27 -2
index 144fe84..8b55747 100644
@@ -350,6 +350,14 @@ struct dma_features {
 
 #define JUMBO_LEN		9000
 
+/* MTL algorithms identifiers */
+#define MTL_TX_ALGORITHM_WRR	0x0
+#define MTL_TX_ALGORITHM_WFQ	0x1
+#define MTL_TX_ALGORITHM_DWRR	0x2
+#define MTL_TX_ALGORITHM_PRIO	0x3
+#define MTL_RX_ALGORITHM_SP	0x4
+#define MTL_RX_ALGORITHM_WSP	0x5
+
 /* Descriptors helpers */
 struct stmmac_desc_ops {
 	/* DMA RX descriptor ring initialization */
@@ -455,16 +463,32 @@ struct stmmac_ops {
 	int (*rx_ipc)(struct mac_device_info *hw);
 	/* Enable RX Queues */
 	void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
+	/* RX Queues Priority */
+	void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
+	/* TX Queues Priority */
+	void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
+	/* Program RX Algorithms */
+	void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg);
+	/* Program TX Algorithms */
+	void (*prog_mtl_tx_algorithms)(struct mac_device_info *hw, u32 tx_alg);
+	/* RX MTL queue to RX dma mapping */
+	void (*map_mtl_to_dma)(struct mac_device_info *hw, u32 queue, u32 chan);
+	/* Set MTL TX queues weight */
+	void (*set_mtl_tx_queue_weight)(struct mac_device_info *hw,
+					u32 weight, u32 queue);
 	/* Dump MAC registers */
 	void (*dump_regs)(struct mac_device_info *hw);
 	/* Handle extra events on specific interrupts hw dependent */
 	int (*host_irq_status)(struct mac_device_info *hw,
 			       struct stmmac_extra_stats *x);
+	/* Handle MTL interrupts */
+	int (*host_mtl_irq_status)(struct mac_device_info *hw, u32 chan);
 	/* Multicast filter setting */
 	void (*set_filter)(struct mac_device_info *hw, struct net_device *dev);
 	/* Flow control setting */
 	void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex,
-			  unsigned int fc, unsigned int pause_time);
+			  unsigned int fc, unsigned int pause_time,
+			  u32 tx_queues_cnt);
 	/* Set power management mode (e.g. magic frame) */
 	void (*pmt)(struct mac_device_info *hw, unsigned long mode);
 	/* Set/Get Unicast MAC addresses */
@@ -477,7 +501,8 @@ struct stmmac_ops {
 	void (*reset_eee_mode)(struct mac_device_info *hw);
 	void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw);
 	void (*set_eee_pls)(struct mac_device_info *hw, int link);
-	void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x);
+	void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x,
+		      u32 queue);
 	/* PCS calls */
 	void (*pcs_ctrl_ane)(void __iomem *ioaddr, bool ane, bool srgmi_ral,
 			     bool loopback);
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +4 -2
index 91c8926..327dfa5 100644
@@ -220,7 +220,8 @@ static void dwmac1000_set_filter(struct mac_device_info *hw,
 
 
 static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
-				unsigned int fc, unsigned int pause_time)
+				unsigned int fc, unsigned int pause_time,
+				u32 tx_queues_cnt)
 {
 	void __iomem *ioaddr = hw->pcsr;
 	/* Set flow such that DZPQ in Mac Register 6 is 0,
@@ -416,7 +417,8 @@ static void dwmac1000_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv)
 	dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv);
 }
 
-static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
+static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x,
+			    u32 queue)
 {
 	u32 value = readl(ioaddr + GMAC_DEBUG);
 
drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +2 -1
index 8ab5189..c6faa1e 100644
@@ -141,7 +141,8 @@ static void dwmac100_set_filter(struct mac_device_info *hw,
 }
 
 static void dwmac100_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
-			       unsigned int fc, unsigned int pause_time)
+			       unsigned int fc, unsigned int pause_time,
+			       u32 tx_queues_cnt)
 {
 	void __iomem *ioaddr = hw->pcsr;
 	unsigned int flow = MAC_FLOW_CTRL_ENABLE;
drivers/net/ethernet/stmicro/stmmac/dwmac4.h +38 -1
index db45134..414070c 100644
@@ -22,7 +22,12 @@
 #define GMAC_HASH_TAB_32_63		0x00000014
 #define GMAC_RX_FLOW_CTRL		0x00000090
 #define GMAC_QX_TX_FLOW_CTRL(x)		(0x70 + x * 4)
+#define GMAC_TXQ_PRTY_MAP0		0x98
+#define GMAC_TXQ_PRTY_MAP1		0x9C
 #define GMAC_RXQ_CTRL0			0x000000a0
+#define GMAC_RXQ_CTRL1			0x000000a4
+#define GMAC_RXQ_CTRL2			0x000000a8
+#define GMAC_RXQ_CTRL3			0x000000ac
 #define GMAC_INT_STATUS			0x000000b0
 #define GMAC_INT_EN			0x000000b4
 #define GMAC_PCS_BASE			0x000000e0
@@ -53,6 +58,14 @@
 /* MAC Flow Control RX */
 #define GMAC_RX_FLOW_CTRL_RFE		BIT(0)
 
+/* RX Queues Priorities */
+#define GMAC_RXQCTRL_PSRQX_MASK(x)	GENMASK(7 + ((x) * 8), 0 + ((x) * 8))
+#define GMAC_RXQCTRL_PSRQX_SHIFT(x)	((x) * 8)
+
+/* TX Queues Priorities */
+#define GMAC_TXQCTRL_PSTQX_MASK(x)	GENMASK(7 + ((x) * 8), 0 + ((x) * 8))
+#define GMAC_TXQCTRL_PSTQX_SHIFT(x)	((x) * 8)
+
 /* MAC Flow Control TX */
 #define GMAC_TX_FLOW_CTRL_TFE		BIT(1)
 #define GMAC_TX_FLOW_CTRL_PT_SHIFT	16
@@ -161,8 +174,25 @@ enum power_event {
 #define GMAC_HI_REG_AE			BIT(31)
 
 /*  MTL registers */
+#define MTL_OPERATION_MODE		0x00000c00
+#define MTL_OPERATION_SCHALG_MASK	GENMASK(6, 5)
+#define MTL_OPERATION_SCHALG_WRR	(0x0 << 5)
+#define MTL_OPERATION_SCHALG_WFQ	(0x1 << 5)
+#define MTL_OPERATION_SCHALG_DWRR	(0x2 << 5)
+#define MTL_OPERATION_SCHALG_PRIO	(0x3 << 5)
+#define MTL_OPERATION_RAA		BIT(2)
+#define MTL_OPERATION_RAA_SP		(0x0 << 2)
+#define MTL_OPERATION_RAA_WSP		(0x1 << 2)
+
 #define MTL_INT_STATUS			0x00000c20
-#define MTL_INT_Q0			BIT(0)
+#define MTL_INT_QX(q)			BIT(q)
+
+#define MTL_RXQ_DMA_MAP0		0x00000c30 /* queue 0 to 3 */
+#define MTL_RXQ_DMA_MAP1		0x00000c34 /* queue 4 to 7 */
+#define MTL_RXQ_DMA_Q04MDMACH_MASK	GENMASK(3, 0)
+#define MTL_RXQ_DMA_Q04MDMACH(x)	((x) << 0)
+#define MTL_RXQ_DMA_QXMDMACH_MASK(x)	GENMASK(11 + (8 * ((x) - 1)), 8 * (x))
+#define MTL_RXQ_DMA_QXMDMACH(chan, q)	((chan) << (8 * (q)))
 
 #define MTL_CHAN_BASE_ADDR		0x00000d00
 #define MTL_CHAN_BASE_OFFSET		0x40
@@ -201,6 +231,13 @@ enum power_event {
 #define MTL_OP_MODE_RTC_96		(2 << MTL_OP_MODE_RTC_SHIFT)
 #define MTL_OP_MODE_RTC_128		(3 << MTL_OP_MODE_RTC_SHIFT)
 
+/* MTL Queue Quantum Weight */
+#define MTL_TXQ_WEIGHT_BASE_ADDR	0x00000d18
+#define MTL_TXQ_WEIGHT_BASE_OFFSET	0x40
+#define MTL_TXQX_WEIGHT_BASE_ADDR(x)	(MTL_TXQ_WEIGHT_BASE_ADDR + \
+					((x) * MTL_TXQ_WEIGHT_BASE_OFFSET))
+#define MTL_TXQ_WEIGHT_ISCQW_MASK	GENMASK(20, 0)
+
 /*  MTL debug */
 #define MTL_DEBUG_TXSTSFSTS		BIT(5)
 #define MTL_DEBUG_TXFSTS		BIT(4)
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +165 -29

253 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +16 -5
index 5ff6bc4..f3caef1 100644
@@ -499,6 +499,7 @@ stmmac_set_pauseparam(struct net_device *netdev,
 		      struct ethtool_pauseparam *pause)
 {
 	struct stmmac_priv *priv = netdev_priv(netdev);
+	u32 tx_queues_count = priv->dma_cap.number_tx_queues;
 	struct phy_device *phy = netdev->phydev;
 	int new_pause = FLOW_OFF;
 
@@ -529,7 +530,8 @@ stmmac_set_pauseparam(struct net_device *netdev,
 	}
 
 	priv->hw->mac->flow_ctrl(priv->hw, phy->duplex, priv->flow_ctrl,
-				 priv->pause);
+				 priv->pause, tx_queues_count);
+
 	return 0;
 }
 
@@ -537,7 +539,13 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
 				 struct ethtool_stats *dummy, u64 *data)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
-	int i, j = 0;
+	u32 rx_queues_count = priv->dma_cap.number_rx_queues;
+	u32 tx_queues_count = priv->dma_cap.number_tx_queues;
+	u32 queue_count = 0;
+	int i, j, queue = 0;
+
+	queue_count = (tx_queues_count > rx_queues_count) ?
+		      tx_queues_count : rx_queues_count;
 
 	/* Update the DMA HW counters for dwmac10/100 */
 	if (priv->hw->dma->dma_diagnostic_fr)
@@ -565,9 +573,12 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
 		}
 
 		if ((priv->hw->mac->debug) &&
-		    (priv->synopsys_id >= DWMAC_CORE_3_50))
-			priv->hw->mac->debug(priv->ioaddr,
-					     (void *)&priv->xstats);
+		    (priv->synopsys_id >= DWMAC_CORE_3_50)) {
+			for (queue = 0; queue < queue_count; queue++)
+				priv->hw->mac->debug(priv->ioaddr,
+						     (void *)&priv->xstats,
+						     queue);
+		}
 	}
 	for (i = 0; i < STMMAC_STATS_LEN; i++) {
 		char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +141 -11

211 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +33 -0
index 433a842..f68134c 100644
@@ -338,6 +338,39 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
 
 	of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
 
+	/* Rx MTL algorithms */
+	if (of_property_read_bool(np, "snps,rx-sched-sp"))
+		plat->mtl_rx_algorithm = MTL_RX_ALGORITHM_SP;
+	else if (of_property_read_bool(np, "snps,rx-sched-wsp"))
+		plat->mtl_rx_algorithm = MTL_RX_ALGORITHM_WSP;
+	else
+		plat->mtl_rx_algorithm = MTL_RX_ALGORITHM_SP;
+
+	/* Tx MTL algorithms */
+	if (of_property_read_bool(np, "snps,tx-sched-wrr"))
+		plat->mtl_tx_algorithm = MTL_TX_ALGORITHM_WRR;
+	else if (of_property_read_bool(np, "snps,tx-sched-wfq"))
+		plat->mtl_tx_algorithm = MTL_TX_ALGORITHM_WFQ;
+	else if (of_property_read_bool(np, "snps,tx-sched-dwrr"))
+		plat->mtl_tx_algorithm = MTL_TX_ALGORITHM_DWRR;
+	else if (of_property_read_bool(np, "snps,tx-sched-prio"))
+		plat->mtl_tx_algorithm = MTL_TX_ALGORITHM_PRIO;
+	else
+		plat->mtl_tx_algorithm = MTL_TX_ALGORITHM_WRR;
+
+	/* TX queues weight */
+	of_property_read_u32_array(np, "snps,tx-queue-weight",
+				   plat->tx_queues_weight,
+				   EQOS_MAX_NUMBER_TX_QUEUES);
+
+	/* RX and TX priority */
+	of_property_read_u32_array(np, "snps,rx-queue-prio",
+				   plat->rx_queues_prio,
+				   EQOS_MAX_NUMBER_RX_QUEUES);
+	of_property_read_u32_array(np, "snps,tx-queue-prio",
+				   plat->tx_queues_prio,
+				   EQOS_MAX_NUMBER_TX_QUEUES);
+
 	plat->axi = stmmac_axi_setup(pdev);
 
 	/* clock setup */
include/linux/stmmac.h +8 -0
index fc273e9..98201d4 100644
@@ -32,6 +32,9 @@
 #define STMMAC_RX_COE_TYPE1	1
 #define STMMAC_RX_COE_TYPE2	2
 
+#define EQOS_MAX_NUMBER_TX_QUEUES	8
+#define EQOS_MAX_NUMBER_RX_QUEUES	8
+
 /* Define the macros for CSR clock range parameters to be passed by
  * platform code.
  * This could also be configured at run time using CPU freq framework. */
@@ -147,5 +150,10 @@ struct plat_stmmacenet_data {
 	bool tso_en;
 	int mac_port_sel_speed;
 	bool en_tx_lpi_clockgating;
+	int mtl_tx_algorithm;
+	int mtl_rx_algorithm;
+	u32 tx_queues_weight[EQOS_MAX_NUMBER_TX_QUEUES];
+	u32 rx_queues_prio[EQOS_MAX_NUMBER_RX_QUEUES];
+	u32 tx_queues_prio[EQOS_MAX_NUMBER_TX_QUEUES];
 };
 #endif
Signature · 1 line
2.9.3
maintainer
#2 lore raw

Re: [PATCH net-next v2 1/3] net: stmicro: prepare dwmac4 core for mtl

From: Joao Pinto <[email protected]>
Date: Thu, 16 Feb 2017 11:19:39 +0000

Quoted 13 lines

This patch adds the following features:

a) RX and TX scheduling algorithm configuration (can be configured in the Device Tree)
b) TX VLAN tag priority configuration (can be configured in the Device Tree)
c) RX VLAN tag priority routing configuration (can be configured in the Device Tree)
d) TX weight configuration (can be configured in the Device Tree)
e) RX queue to RX DMA channel mapping
f) RX queue enabling
g) MAC and individual queue related interrupt analysis
h) Flow Control configuration by queue

Quoted 6 lines

The number of RX and TX queues to use comes from the FEATURES register.

With this patch we get the core related operations ready for multiple queue/channel.

This would be so much easier to review if you used one patch for each of those new configuration features.

In fact, it would make an appropriate complete patch series on it's own.

Thanks.

author
#3 lore raw

Re: [PATCH net-next v2 1/3] net: stmicro: prepare dwmac4 core for mtl

Hi David,

Às 6:02 PM de 2/17/2017, David Miller escreveu:

Quoted 21 lines

From: Joao Pinto <[email protected]>
Date: Thu, 16 Feb 2017 11:19:39 +0000

Quoted 18 lines

This patch adds the following features:

a) RX and TX scheduling algorithm configuration (can be configured in the Device Tree)
b) TX VLAN tag priority configuration (can be configured in the Device Tree)
c) RX VLAN tag priority routing configuration (can be configured in the Device Tree)
d) TX weight configuration (can be configured in the Device Tree)
e) RX queue to RX DMA channel mapping
f) RX queue enabling
g) MAC and individual queue related interrupt analysis
h) Flow Control configuration by queue

The number of RX and TX queues to use comes from the FEATURES register.

With this patch we get the core related operations ready for multiple queue/channel.

Quoted 6 lines
Quoted 1 line

This would be so much easier to review if you used one patch for each of those new configuration features.

In fact, it would make an appropriate complete patch series on it's own.

Should I put the multiple queues / channels changes in a single patch or should I break it into a feature change / patch? What would be easier for you to review?

Quoted 3 lines

Thanks.

Thanks.

maintainer
#4 lore raw

Re: [PATCH net-next v2 1/3] net: stmicro: prepare dwmac4 core for mtl

From: Joao Pinto <[email protected]>
Date: Fri, 17 Feb 2017 18:09:06 +0000

Quoted 27 lines

Hi David,

Às 6:02 PM de 2/17/2017, David Miller escreveu:

Quoted 23 lines

From: Joao Pinto <[email protected]>
Date: Thu, 16 Feb 2017 11:19:39 +0000

Quoted 19 lines

This patch adds the following features:

a) RX and TX scheduling algorithm configuration (can be configured in the Device Tree)
b) TX VLAN tag priority configuration (can be configured in the Device Tree)
c) RX VLAN tag priority routing configuration (can be configured in the Device Tree)
d) TX weight configuration (can be configured in the Device Tree)
e) RX queue to RX DMA channel mapping
f) RX queue enabling
g) MAC and individual queue related interrupt analysis
h) Flow Control configuration by queue

The number of RX and TX queues to use comes from the FEATURES register.

With this patch we get the core related operations ready for multiple queue/channel.

Quoted 7 lines
Quoted 4 lines

This would be so much easier to review if you used one patch for each of those new configuration features.

In fact, it would make an appropriate complete patch series on it's own.

Should I put the multiple queues / channels changes in a single patch or should I break it into a feature change / patch? What would be easier for you to review?

Submit the first series, and when that is accepted you can do similarly for the second patch, and then when that's accepted you do the third on in the same manner.

author
#5 lore raw

PATCH v2 2/3 net: stmicro: prepare dwmac4 dma for mtl

In reply to Joao Pinto

This patch adds the following features:

a) RX and TX DMA Operation Mode now setting FIFO size
b) FIFO size is obtained from the FEATURES register or can be set in the Device Tree (fifo depth)
c) Common DMA operations initialization by channel
d) RX DMA initialization by channel
e) TX DMA initialization by channel
f) Debug enhancements (added debug registers to see RX/TX channel State Machine status)
g) DMA IRQ configuration per channel
h) DMA RX/TX start/stop per channel
i) Number of queues / channels set to 1 in dwmac100 and dwmac1000 to ensure compatibility

With this patch we get the dma related operations ready for multiple queue/channel.

---
changes v1->v2:
- No changes, just keep up patch-set version.

 drivers/net/ethernet/stmicro/stmmac/common.h       |  60 ++-
 .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c    |  16 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c |  19 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4.h       |  10 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c   | 297 +++++++++-----
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h   |  25 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c   |  58 +--
 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   |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 450 +++++++++++++++++----
 11 files changed, 700 insertions(+), 268 deletions(-)
drivers/net/ethernet/stmicro/stmmac/common.h +44 -16
index 8b55747..1c586ee 100644
@@ -322,6 +322,9 @@ struct dma_features {
 	/* TX and RX number of queues */
 	unsigned int number_rx_queues;
 	unsigned int number_tx_queues;
+	/* TX and RX fifo sizes */
+	unsigned int rx_fifosz;
+	unsigned int tx_fifosz;
 	/* Alternate (enhanced) DESC mode */
 	unsigned int enh_desc;
 };
@@ -358,6 +361,20 @@ struct dma_features {
 #define MTL_RX_ALGORITHM_SP	0x4
 #define MTL_RX_ALGORITHM_WSP	0x5
 
+enum mtl_fifo_size {
+	FIFO_256 = 0x0,
+	FIFO_512 = 0x1,
+	FIFO_1k = 0x3,
+	FIFO_2k = 0x7,
+	FIFO_4k = 0xf,
+	FIFO_8k = 0x1f,
+	FIFO_16k = 0x3f,
+	FIFO_32k = 0x7f
+};
+
+#define FIFO_SIZE_B(x)		(x)
+#define FIFO_SIZE_KB(x)		((x) * 1024)
+
 /* Descriptors helpers */
 struct stmmac_desc_ops {
 	/* DMA RX descriptor ring initialization */
@@ -421,33 +438,44 @@ 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 */
-	void (*dump_regs) (void __iomem *ioaddr);
-	/* Set tx/rx threshold in the csr6 register
-	 * An invalid value enables the store-and-forward mode */
-	void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode,
-			 int rxfifosz);
+	void (*dump_regs)(void __iomem *ioaddr, u32 number_channels);
+	/* Configure DMA Operation Mode */
+	void (*dma_mode)(void __iomem *ioaddr, u32 txfifosz, u32 rxfifosz,
+			 u32 txmode, u32 rxmode);
+	void (*dma_rx_mode)(void __iomem *ioaddr, u32 mode, u32 queue_fifo,
+			    u32 chan);
+	void (*dma_tx_mode)(void __iomem *ioaddr, u32 mode, u32 queue_fifo,
+			    u32 chan);
 	/* To track extra statistic (if supported) */
 	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 (*start_tx) (void __iomem *ioaddr);
-	void (*stop_tx) (void __iomem *ioaddr);
-	void (*start_rx) (void __iomem *ioaddr);
-	void (*stop_rx) (void __iomem *ioaddr);
-	int (*dma_interrupt) (void __iomem *ioaddr,
-			      struct stmmac_extra_stats *x);
+	void (*enable_dma_irq)(void __iomem *ioaddr, u32 chan);
+	void (*disable_dma_irq)(void __iomem *ioaddr, u32 chan);
+	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, u32 chan);
 	/* If supported then get the optional core features */
 	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 (*set_tx_ring_len)(void __iomem *ioaddr, u32 len);
-	void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len);
+	void (*rx_watchdog)(void __iomem *ioaddr, u32 num_channels, u32 riwt);
+	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);
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +12 -4
index fbaec0f..9d0a283 100644
@@ -148,8 +148,9 @@ static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
 	return csr6;
 }
 
-static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
-					 int rxmode, int rxfifosz)
+static void dwmac1000_dma_operation_mode(void __iomem *ioaddr,
+					 u32 txfifosz, u32 rxfifosz,
+					 u32 txmode, u32 rxmode)
 {
 	u32 csr6 = readl(ioaddr + DMA_CONTROL);
 
@@ -201,7 +202,7 @@ static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
 	writel(csr6, ioaddr + DMA_CONTROL);
 }
 
-static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
+static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 number_channels)
 {
 	int i;
 	pr_info(" DMA registers\n");
@@ -249,9 +250,16 @@ static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
 	dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
 	/* Alternate (enhanced) DESC mode */
 	dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
+	/* TX and RX number of channels */
+	dma_cap->number_rx_channel = 1;
+	dma_cap->number_tx_channel = 1;
+	/* TX and RX number of queues */
+	dma_cap->number_rx_queues = 1;
+	dma_cap->number_tx_queues = 1;
 }
 
-static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt)
+static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 number_channels,
+				  u32 riwt)
 {
 	writel(riwt, ioaddr + DMA_RX_WATCHDOG);
 }
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +16 -3
index d40e91e8..accec0e 100644
@@ -51,8 +51,9 @@ static void dwmac100_dma_init(void __iomem *ioaddr,
  * The transmit threshold can be programmed by setting the TTC bits in the DMA
  * control register.
  */
-static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
-					int rxmode, int rxfifosz)
+static void dwmac100_dma_operation_mode(void __iomem *ioaddr,
+					u32 txfifosz, u32 rxfifosz,
+					u32 txmode, u32 rxmode)
 {
 	u32 csr6 = readl(ioaddr + DMA_CONTROL);
 
@@ -66,7 +67,7 @@ static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
 	writel(csr6, ioaddr + DMA_CONTROL);
 }
 
-static void dwmac100_dump_dma_regs(void __iomem *ioaddr)
+static void dwmac100_dump_dma_regs(void __iomem *ioaddr, u32 number_channels)
 {
 	int i;
 
@@ -110,6 +111,17 @@ static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
 	}
 }
 
+static void dwmac100_get_hw_feature(void __iomem *ioaddr,
+				    struct dma_features *dma_cap)
+{
+	/* TX and RX number of channels */
+	dma_cap->number_rx_channel = 1;
+	dma_cap->number_tx_channel = 1;
+	/* TX and RX number of queues */
+	dma_cap->number_rx_queues = 1;
+	dma_cap->number_tx_queues = 1;
+}
+
 const struct stmmac_dma_ops dwmac100_dma_ops = {
 	.reset = dwmac_dma_reset,
 	.init = dwmac100_dma_init,
@@ -124,4 +136,5 @@ const struct stmmac_dma_ops dwmac100_dma_ops = {
 	.start_rx = dwmac_dma_start_rx,
 	.stop_rx = dwmac_dma_stop_rx,
 	.dma_interrupt = dwmac_dma_interrupt,
+	.get_hw_feature = dwmac100_get_hw_feature,
 };
drivers/net/ethernet/stmicro/stmmac/dwmac4.h +9 -1
index 414070c..671ee9f 100644
@@ -161,6 +161,8 @@ enum power_event {
 /* MAC HW features1 bitmap */
 #define GMAC_HW_FEAT_AVSEL		BIT(20)
 #define GMAC_HW_TSOEN			BIT(18)
+#define GMAC_HW_TXFIFOSIZE		GENMASK(10, 6)
+#define GMAC_HW_RXFIFOSIZE		GENMASK(4, 0)
 
 /* MAC HW features2 bitmap */
 #define GMAC_HW_FEAT_TXCHCNT		GENMASK(21, 18)
@@ -205,11 +207,17 @@ enum power_event {
 #define MTL_CHAN_RX_OP_MODE(x)		(MTL_CHANX_BASE_ADDR(x) + 0x30)
 #define MTL_CHAN_RX_DEBUG(x)		(MTL_CHANX_BASE_ADDR(x) + 0x38)
 
+#define MTL_RX_OP_MODE_RQS_MASK		GENMASK(31, 20)
+#define MTL_RX_OP_MODE_RQS_SHIFT	20
+#define MTL_RX_OP_MODE_RQS(x)		((x) << MTL_RX_OP_MODE_RQS_SHIFT)
+
 #define MTL_OP_MODE_RSF			BIT(5)
 #define MTL_OP_MODE_TXQEN		BIT(3)
 #define MTL_OP_MODE_TSF			BIT(1)
 
-#define MTL_OP_MODE_TQS_MASK		GENMASK(24, 16)
+#define MTL_TX_OP_MODE_TQS_MASK		GENMASK(24, 16)
+#define MTL_TX_OP_MODE_TQS_SHIFT	16
+#define MTL_TX_OP_MODE_TQS(x)		((x) << MTL_TX_OP_MODE_TQS_SHIFT)
 
 #define MTL_OP_MODE_TTC_MASK		0x70
 #define MTL_OP_MODE_TTC_SHIFT		4
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +200 -97

412 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h +10 -15
index 1b06df7..a485201 100644
@@ -14,11 +14,6 @@
 #ifndef __DWMAC4_DMA_H__
 #define __DWMAC4_DMA_H__
 
-/* Define the max channel number used for tx (also rx).
- * dwmac4 accepts up to 8 channels for TX (and also 8 channels for RX
- */
-#define DMA_CHANNEL_NB_MAX		1
-
 #define DMA_BUS_MODE			0x00001000
 #define DMA_SYS_BUS_MODE		0x00001004
 #define DMA_STATUS			0x00001008
@@ -185,17 +180,17 @@
 
 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_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_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, 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);
-void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len);
+			struct stmmac_extra_stats *x, u32 chan);
+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);
 
drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c +29 -29

146 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +8 -7
index 56e485f..612720a 100644
@@ -137,13 +137,14 @@
 #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_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);
-int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x);
+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, 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, u32 chan);
 int dwmac_dma_reset(void __iomem *ioaddr);
 
 #endif /* __DWMAC_DMA_H__ */
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c +7 -7
index e60bfca..38f9430 100644
@@ -47,38 +47,38 @@ 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);
 }
 
-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;
@@ -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) */
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +3 -1
index f3caef1..7a61636 100644
@@ -793,8 +793,10 @@ 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->dma_cap.number_rx_channel,
+				   priv->rx_riwt);
 	return 0;
 }
 
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +362 -88

603 lines not on this page · raw message

Signature · 1 line
2.9.3
author
#6 lore raw

PATCH v2 3/3 net: stmicro: multiple buffer support

In reply to Joao Pinto

This patch adds the following features:

a) Creation of tx_queue and rx_queue structures (stmmac.h), each containing relevant queue related parameters (skbuff_dma, skbuff, etc.).
b) tx_queue and rx_queue allocation is dynamic and done accordingly with the number of RX queues and TX queues existent in the controller
c) Since the number of RX queues and TX queues can be different, functions were broken into RX and TX related to enable separated treatment when possible
d) stmmac_main had to be adapted to enable the multiple buffering mechanism

---
changes v1->v2:
- No changes, just keep up patch-set version.

 drivers/net/ethernet/stmicro/stmmac/chain_mode.c  |   44 +-
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c   |   47 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h      |   47 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1325 ++++++++++++++-------
 4 files changed, 990 insertions(+), 473 deletions(-)
drivers/net/ethernet/stmicro/stmmac/chain_mode.c +24 -20
index 01a8c02..31978a6 100644
@@ -26,9 +26,10 @@
 
 static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 {
-	struct stmmac_priv *priv = (struct stmmac_priv *)p;
-	unsigned int entry = priv->cur_tx;
-	struct dma_desc *desc = priv->dma_tx + entry;
+	struct stmmac_tx_queue *tx_queue = (struct stmmac_tx_queue *)p;
+	struct stmmac_priv *priv = tx_queue->priv_data;
+	unsigned int entry = tx_queue->cur_tx;
+	struct dma_desc *desc = tx_queue->dma_tx + entry;
 	unsigned int nopaged_len = skb_headlen(skb);
 	unsigned int bmax, des2;
 	unsigned int i = 1, len;
@@ -45,16 +46,16 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 	desc->des2 = cpu_to_le32(des2);
 	if (dma_mapping_error(priv->device, des2))
 		return -1;
-	priv->tx_skbuff_dma[entry].buf = des2;
-	priv->tx_skbuff_dma[entry].len = bmax;
+	tx_queue->tx_skbuff_dma[entry].buf = des2;
+	tx_queue->tx_skbuff_dma[entry].len = bmax;
 	/* do not close the descriptor and do not set own bit */
 	priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
 					0, false);
 
 	while (len != 0) {
-		priv->tx_skbuff[entry] = NULL;
+		tx_queue->tx_skbuff[entry] = NULL;
 		entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
-		desc = priv->dma_tx + entry;
+		desc = tx_queue->dma_tx + entry;
 
 		if (len > bmax) {
 			des2 = dma_map_single(priv->device,
@@ -63,8 +64,9 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 			desc->des2 = cpu_to_le32(des2);
 			if (dma_mapping_error(priv->device, des2))
 				return -1;
-			priv->tx_skbuff_dma[entry].buf = des2;
-			priv->tx_skbuff_dma[entry].len = bmax;
+			tx_queue->tx_skbuff_dma[entry].buf = des2;
+			tx_queue->tx_skbuff_dma[entry].len = bmax;
+
 			priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
 							STMMAC_CHAIN_MODE, 1,
 							false);
@@ -77,8 +79,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 			desc->des2 = cpu_to_le32(des2);
 			if (dma_mapping_error(priv->device, des2))
 				return -1;
-			priv->tx_skbuff_dma[entry].buf = des2;
-			priv->tx_skbuff_dma[entry].len = len;
+			tx_queue->tx_skbuff_dma[entry].buf = des2;
+			tx_queue->tx_skbuff_dma[entry].len = len;
 			/* last descriptor can be set now */
 			priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
 							STMMAC_CHAIN_MODE, 1,
@@ -87,7 +89,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 		}
 	}
 
-	priv->cur_tx = entry;
+	tx_queue->cur_tx = entry;
 
 	return entry;
 }
@@ -136,32 +138,34 @@ static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
 
 static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
 {
-	struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
+	struct stmmac_rx_queue *rx_queue = (struct stmmac_rx_queue *)priv_ptr;
+	struct stmmac_priv *priv = rx_queue->priv_data;
 
 	if (priv->hwts_rx_en && !priv->extend_desc)
 		/* NOTE: Device will overwrite des3 with timestamp value if
 		 * 1588-2002 time stamping is enabled, hence reinitialize it
 		 * to keep explicit chaining in the descriptor.
 		 */
-		p->des3 = cpu_to_le32((unsigned int)(priv->dma_rx_phy +
-				      (((priv->dirty_rx) + 1) %
+		p->des3 = cpu_to_le32((unsigned int)(rx_queue->dma_rx_phy +
+				      (((rx_queue->dirty_rx) + 1) %
 				       DMA_RX_SIZE) *
 				      sizeof(struct dma_desc)));
 }
 
 static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
 {
-	struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
-	unsigned int entry = priv->dirty_tx;
+	struct stmmac_tx_queue *tx_queue = (struct stmmac_tx_queue *)priv_ptr;
+	struct stmmac_priv *priv = tx_queue->priv_data;
+	unsigned int entry = tx_queue->dirty_tx;
 
-	if (priv->tx_skbuff_dma[entry].last_segment && !priv->extend_desc &&
+	if (tx_queue->tx_skbuff_dma[entry].last_segment && !priv->extend_desc &&
 	    priv->hwts_tx_en)
 		/* NOTE: Device will overwrite des3 with timestamp value if
 		 * 1588-2002 time stamping is enabled, hence reinitialize it
 		 * to keep explicit chaining in the descriptor.
 		 */
-		p->des3 = cpu_to_le32((unsigned int)((priv->dma_tx_phy +
-				      ((priv->dirty_tx + 1) % DMA_TX_SIZE))
+		p->des3 = cpu_to_le32((unsigned int)((tx_queue->dma_tx_phy +
+				      ((tx_queue->dirty_tx + 1) % DMA_TX_SIZE))
 				      * sizeof(struct dma_desc)));
 }
 
drivers/net/ethernet/stmicro/stmmac/ring_mode.c +25 -22

104 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/stmmac.h +31 -16

77 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +910 -415

2,115 lines not on this page · raw message

Signature · 1 line
2.9.3