Skip to contentSkip to conversation

Add support for XGMAC2 in stmmac

PATCH Superseded Jose Abreu 2 participants 13 messages Aug 3, 2018

Subsystems (5)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Jose Abreu

author
#0 lore raw

v2 cover Add support for XGMAC2 in stmmac

This series adds support for 10Gigabit IP in stmmac. The IP is called XGMAC2 and has many similarities with GMAC4. Due to this, its relatively easy to incorporate this new IP into stmmac driver by adding a new block and filling the necessary callbacks.

The functionality added by this series is still reduced but its only a starting point which will later be expanded.

I splitted the patches into funcionality and to ease the review. Only the patch 8/9 really enables the XGMAC2 block by adding a new compatible string.

Version 2 addresses review comments of Andrew Lunn.

NOTE: Although the IP supports 10G, for now it was only possible to test it at 1G speed due to 10G PHY HW shipping problems. Here follows iperf3 results at 1G:

---

# iperf3 -c 192.168.0.10
Connecting to host 192.168.0.10, port 5201
[  4] local 192.168.0.3 port 39178 connected to 192.168.0.10 port 5201
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec   110 MBytes   920 Mbits/sec    0    482 KBytes
[  4]   1.00-2.00   sec   113 MBytes   946 Mbits/sec    0    482 KBytes
[  4]   2.00-3.00   sec   112 MBytes   937 Mbits/sec    0    482 KBytes
[  4]   3.00-4.00   sec   113 MBytes   946 Mbits/sec    0    482 KBytes
[  4]   4.00-5.00   sec   112 MBytes   935 Mbits/sec    0    482 KBytes
[  4]   5.00-6.00   sec   113 MBytes   946 Mbits/sec    0    482 KBytes
[  4]   6.00-7.00   sec   112 MBytes   937 Mbits/sec    0    482 KBytes
[  4]   7.00-8.00   sec   113 MBytes   946 Mbits/sec    0    482 KBytes
[  4]   8.00-9.00   sec   112 MBytes   937 Mbits/sec    0    482 KBytes
[  4]   9.00-10.00  sec   113 MBytes   946 Mbits/sec    0    482 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec  1.09 GBytes   940 Mbits/sec    0             sender
[  4]   0.00-10.00  sec  1.09 GBytes   938 Mbits/sec                  receiver
---
Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
Cc Andrew Lunn <[email protected]>

Jose Abreu (9):
net: stmmac: Add XGMAC 2.10 HWIF entry
net: stmmac: Add MAC related callbacks for XGMAC2
net: stmmac: Add DMA related callbacks for XGMAC2
net: stmmac: Add descriptor related callbacks for XGMAC2
net: stmmac: Add MDIO related functions for XGMAC2
net: stmmac: Add PTP support for XGMAC2
net: stmmac: Integrate XGMAC into main driver flow
net: stmmac: Add the bindings parsing for XGMAC2
dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.

 Documentation/devicetree/bindings/net/stmmac.txt   |   5 +-
 drivers/net/ethernet/stmicro/stmmac/Makefile       |   3 +-
 drivers/net/ethernet/stmicro/stmmac/common.h       |  17 +-
 .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |   2 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h     | 227 ++++++++++++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    | 371 +++++++++++++++++++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 ++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/hwif.c         |  31 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h         |   3 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  67 +++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  | 101 ++++-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   6 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |   6 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h   |   1 +
 include/linux/stmmac.h                             |   1 +
 16 files changed, 1497 insertions(+), 34 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
Signature · 1 line
2.7.4
author
#1 lore raw

PATCH v2 1/9 net: stmmac: Add XGMAC 2.10 HWIF entry

Add a new entry to HWIF table for XGMAC 2.10. For now we fill it with empty callbacks which will be added in posterior patches.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
---
 drivers/net/ethernet/stmicro/stmmac/common.h | 14 +++++++------
 drivers/net/ethernet/stmicro/stmmac/hwif.c   | 31 ++++++++++++++++++++++++++--
 include/linux/stmmac.h                       |  1 +
 3 files changed, 38 insertions(+), 8 deletions(-)
drivers/net/ethernet/stmicro/stmmac/common.h +8 -6
index 78fd0f8b8e81..3fb81acbd274 100644
@@ -36,12 +36,14 @@
 #include "mmc.h"
 
 /* Synopsys Core versions */
-#define	DWMAC_CORE_3_40	0x34
-#define	DWMAC_CORE_3_50	0x35
-#define	DWMAC_CORE_4_00	0x40
-#define DWMAC_CORE_4_10	0x41
-#define DWMAC_CORE_5_00 0x50
-#define DWMAC_CORE_5_10 0x51
+#define	DWMAC_CORE_3_40		0x34
+#define	DWMAC_CORE_3_50		0x35
+#define	DWMAC_CORE_4_00		0x40
+#define DWMAC_CORE_4_10		0x41
+#define DWMAC_CORE_5_00		0x50
+#define DWMAC_CORE_5_10		0x51
+#define DWXGMAC_CORE_2_10	0x21
+
 #define STMMAC_CHAN0	0	/* Always supported and default for all chips */
 
 /* These need to be power of two, and >= 4 */
drivers/net/ethernet/stmicro/stmmac/hwif.c +29 -2
index 1f50e83cafb2..24f5ff175aa4 100644
@@ -72,6 +72,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
 static const struct stmmac_hwif_entry {
 	bool gmac;
 	bool gmac4;
+	bool xgmac;
 	u32 min_id;
 	const struct stmmac_regs_off regs;
 	const void *desc;
@@ -87,6 +88,7 @@ static const struct stmmac_hwif_entry {
 	{
 		.gmac = false,
 		.gmac4 = false,
+		.xgmac = false,
 		.min_id = 0,
 		.regs = {
 			.ptp_off = PTP_GMAC3_X_OFFSET,
@@ -103,6 +105,7 @@ static const struct stmmac_hwif_entry {
 	}, {
 		.gmac = true,
 		.gmac4 = false,
+		.xgmac = false,
 		.min_id = 0,
 		.regs = {
 			.ptp_off = PTP_GMAC3_X_OFFSET,
@@ -119,6 +122,7 @@ static const struct stmmac_hwif_entry {
 	}, {
 		.gmac = false,
 		.gmac4 = true,
+		.xgmac = false,
 		.min_id = 0,
 		.regs = {
 			.ptp_off = PTP_GMAC4_OFFSET,
@@ -135,6 +139,7 @@ static const struct stmmac_hwif_entry {
 	}, {
 		.gmac = false,
 		.gmac4 = true,
+		.xgmac = false,
 		.min_id = DWMAC_CORE_4_00,
 		.regs = {
 			.ptp_off = PTP_GMAC4_OFFSET,
@@ -151,6 +156,7 @@ static const struct stmmac_hwif_entry {
 	}, {
 		.gmac = false,
 		.gmac4 = true,
+		.xgmac = false,
 		.min_id = DWMAC_CORE_4_10,
 		.regs = {
 			.ptp_off = PTP_GMAC4_OFFSET,
@@ -167,6 +173,7 @@ static const struct stmmac_hwif_entry {
 	}, {
 		.gmac = false,
 		.gmac4 = true,
+		.xgmac = false,
 		.min_id = DWMAC_CORE_5_10,
 		.regs = {
 			.ptp_off = PTP_GMAC4_OFFSET,
@@ -180,11 +187,29 @@ static const struct stmmac_hwif_entry {
 		.tc = &dwmac510_tc_ops,
 		.setup = dwmac4_setup,
 		.quirks = NULL,
-	}
+	}, {
+		.gmac = false,
+		.gmac4 = false,
+		.xgmac = true,
+		.min_id = DWXGMAC_CORE_2_10,
+		.regs = {
+			.ptp_off = 0,
+			.mmc_off = 0,
+		},
+		.desc = NULL,
+		.dma = NULL,
+		.mac = NULL,
+		.hwtimestamp = NULL,
+		.mode = NULL,
+		.tc = NULL,
+		.setup = NULL,
+		.quirks = NULL,
+	},
 };
 
 int stmmac_hwif_init(struct stmmac_priv *priv)
 {
+	bool needs_xgmac = priv->plat->has_xgmac;
 	bool needs_gmac4 = priv->plat->has_gmac4;
 	bool needs_gmac = priv->plat->has_gmac;
 	const struct stmmac_hwif_entry *entry;
@@ -195,7 +220,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
 
 	if (needs_gmac) {
 		id = stmmac_get_id(priv, GMAC_VERSION);
-	} else if (needs_gmac4) {
+	} else if (needs_gmac4 || needs_xgmac) {
 		id = stmmac_get_id(priv, GMAC4_VERSION);
 	} else {
 		id = 0;
@@ -229,6 +254,8 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
 			continue;
 		if (needs_gmac4 ^ entry->gmac4)
 			continue;
+		if (needs_xgmac ^ entry->xgmac)
+			continue;
 		/* Use synopsys_id var because some setups can override this */
 		if (priv->synopsys_id < entry->min_id)
 			continue;
include/linux/stmmac.h +1 -0
index 32feac5bbd75..c43e9a01b892 100644
@@ -190,5 +190,6 @@ struct plat_stmmacenet_data {
 	bool tso_en;
 	int mac_port_sel_speed;
 	bool en_tx_lpi_clockgating;
+	int has_xgmac;
 };
 #endif
Signature · 1 line
2.7.4
author
#2 lore raw

PATCH v2 2/9 net: stmmac: Add MAC related callbacks for XGMAC2

In reply to Jose Abreu

Add the MAC related callbacks for the new IP block XGMAC2.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
---
 drivers/net/ethernet/stmicro/stmmac/Makefile       |   2 +-
 drivers/net/ethernet/stmicro/stmmac/common.h       |   3 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h     | 141 ++++++++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    | 371 +++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/hwif.c         |   4 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h         |   1 +
 6 files changed, 519 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
drivers/net/ethernet/stmicro/stmmac/Makefile +1 -1
index 68e9e2640c62..a6cf632c9592 100644
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\
 	      dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o	\
 	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o	\
 	      dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
-	      stmmac_tc.o $(stmmac-y)
+	      stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)	+= stmmac-platform.o
drivers/net/ethernet/stmicro/stmmac/common.h +3 -0
index 3fb81acbd274..1854f270ad66 100644
@@ -400,6 +400,8 @@ struct mac_link {
 	u32 speed10;
 	u32 speed100;
 	u32 speed1000;
+	u32 speed2500;
+	u32 speed10000;
 	u32 duplex;
 };
 
@@ -441,6 +443,7 @@ struct stmmac_rx_routing {
 int dwmac100_setup(struct stmmac_priv *priv);
 int dwmac1000_setup(struct stmmac_priv *priv);
 int dwmac4_setup(struct stmmac_priv *priv);
+int dwxgmac2_setup(struct stmmac_priv *priv);
 
 void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
 			 unsigned int high, unsigned int low);
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h new file +141 -0

141 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c new file +371 -0

371 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/hwif.c +2 -2
index 24f5ff175aa4..4fa46f064720 100644
@@ -198,11 +198,11 @@ static const struct stmmac_hwif_entry {
 		},
 		.desc = NULL,
 		.dma = NULL,
-		.mac = NULL,
+		.mac = &dwxgmac210_ops,
 		.hwtimestamp = NULL,
 		.mode = NULL,
 		.tc = NULL,
-		.setup = NULL,
+		.setup = dwxgmac2_setup,
 		.quirks = NULL,
 	},
 };
drivers/net/ethernet/stmicro/stmmac/hwif.h +1 -0
index 79911eefc2a7..ff0fd6978260 100644
@@ -479,6 +479,7 @@ extern const struct stmmac_ops dwmac410_ops;
 extern const struct stmmac_dma_ops dwmac410_dma_ops;
 extern const struct stmmac_ops dwmac510_ops;
 extern const struct stmmac_tc_ops dwmac510_tc_ops;
+extern const struct stmmac_ops dwxgmac210_ops;
 
 #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
 #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
Signature · 1 line
2.7.4
author
#3 lore raw

PATCH v2 3/9 net: stmmac: Add DMA related callbacks for XGMAC2

In reply to Jose Abreu

Add the DMA related callbacks for the new IP block XGMAC2.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
---
 drivers/net/ethernet/stmicro/stmmac/Makefile       |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h     |  56 +++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/hwif.c         |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h         |   1 +
 5 files changed, 469 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
drivers/net/ethernet/stmicro/stmmac/Makefile +1 -1
index a6cf632c9592..da40d3bba037 100644
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\
 	      dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o	\
 	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o	\
 	      dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
-	      stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
+	      stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)	+= stmmac-platform.o
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +56 -0

60 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c new file +410 -0

410 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/hwif.c +1 -1
index 4fa46f064720..4030199aee7b 100644
@@ -197,7 +197,7 @@ static const struct stmmac_hwif_entry {
 			.mmc_off = 0,
 		},
 		.desc = NULL,
-		.dma = NULL,
+		.dma = &dwxgmac210_dma_ops,
 		.mac = &dwxgmac210_ops,
 		.hwtimestamp = NULL,
 		.mode = NULL,
drivers/net/ethernet/stmicro/stmmac/hwif.h +1 -0
index ff0fd6978260..3106eaca60cd 100644
@@ -480,6 +480,7 @@ extern const struct stmmac_dma_ops dwmac410_dma_ops;
 extern const struct stmmac_ops dwmac510_ops;
 extern const struct stmmac_tc_ops dwmac510_tc_ops;
 extern const struct stmmac_ops dwxgmac210_ops;
+extern const struct stmmac_dma_ops dwxgmac210_dma_ops;
 
 #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
 #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
Signature · 1 line
2.7.4
author
#4 lore raw

PATCH v2 4/9 net: stmmac: Add descriptor related callbacks for XGMAC2

In reply to Jose Abreu

Add the descriptor related callbacks for the new IP block XGMAC2.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
---
 drivers/net/ethernet/stmicro/stmmac/Makefile       |   3 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h     |  30 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 +++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/hwif.c         |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h         |   1 +
 5 files changed, 314 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
drivers/net/ethernet/stmicro/stmmac/Makefile +2 -1
index da40d3bba037..99967a80a8c8 100644
@@ -5,7 +5,8 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\
 	      dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o	\
 	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o	\
 	      dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
-	      stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
+	      stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
+	      $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)	+= stmmac-platform.o
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +30 -0
index ddd23f8559df..d090cbb501f2 100644
@@ -194,4 +194,34 @@
 #define XGMAC_TPS			BIT(1)
 #define XGMAC_TI			BIT(0)
 
+/* Descriptors */
+#define XGMAC_TDES2_IOC			BIT(31)
+#define XGMAC_TDES2_TTSE		BIT(30)
+#define XGMAC_TDES2_B2L			GENMASK(29, 16)
+#define XGMAC_TDES2_B2L_SHIFT		16
+#define XGMAC_TDES2_B1L			GENMASK(13, 0)
+#define XGMAC_TDES3_OWN			BIT(31)
+#define XGMAC_TDES3_CTXT		BIT(30)
+#define XGMAC_TDES3_FD			BIT(29)
+#define XGMAC_TDES3_LD			BIT(28)
+#define XGMAC_TDES3_CPC			GENMASK(27, 26)
+#define XGMAC_TDES3_CPC_SHIFT		26
+#define XGMAC_TDES3_TCMSSV		BIT(26)
+#define XGMAC_TDES3_THL			GENMASK(22, 19)
+#define XGMAC_TDES3_THL_SHIFT		19
+#define XGMAC_TDES3_TSE			BIT(18)
+#define XGMAC_TDES3_CIC			GENMASK(17, 16)
+#define XGMAC_TDES3_CIC_SHIFT		16
+#define XGMAC_TDES3_TPL			GENMASK(17, 0)
+#define XGMAC_TDES3_FL			GENMASK(14, 0)
+#define XGMAC_RDES3_OWN			BIT(31)
+#define XGMAC_RDES3_CTXT		BIT(30)
+#define XGMAC_RDES3_IOC			BIT(30)
+#define XGMAC_RDES3_LD			BIT(28)
+#define XGMAC_RDES3_CDA			BIT(27)
+#define XGMAC_RDES3_ES			BIT(15)
+#define XGMAC_RDES3_PL			GENMASK(13, 0)
+#define XGMAC_RDES3_TSD			BIT(6)
+#define XGMAC_RDES3_TSA			BIT(4)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c new file +280 -0

280 lines not on this page · raw message

drivers/net/ethernet/stmicro/stmmac/hwif.c +1 -1
index 4030199aee7b..4b4ba1c8bad5 100644
@@ -196,7 +196,7 @@ static const struct stmmac_hwif_entry {
 			.ptp_off = 0,
 			.mmc_off = 0,
 		},
-		.desc = NULL,
+		.desc = &dwxgmac210_desc_ops,
 		.dma = &dwxgmac210_dma_ops,
 		.mac = &dwxgmac210_ops,
 		.hwtimestamp = NULL,
drivers/net/ethernet/stmicro/stmmac/hwif.h +1 -0
index 3106eaca60cd..92b8944f26e3 100644
@@ -481,6 +481,7 @@ extern const struct stmmac_ops dwmac510_ops;
 extern const struct stmmac_tc_ops dwmac510_tc_ops;
 extern const struct stmmac_ops dwxgmac210_ops;
 extern const struct stmmac_dma_ops dwxgmac210_dma_ops;
+extern const struct stmmac_desc_ops dwxgmac210_desc_ops;
 
 #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
 #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
Signature · 1 line
2.7.4
author
#5 lore raw

PATCH v2 5/9 net: stmmac: Add MDIO related functions for XGMAC2

In reply to Jose Abreu

Add the MDIO related funcionalities for the new IP block XGMAC2.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
Cc Andrew Lunn <[email protected]>

---
Changes from v1:
- Remove C45 support (Andrew)
- Add define for bits (Andrew)
- Remove uneeded cast (Andrew)
- Use different callbacks instead of if's (Andrew)

---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 101 +++++++++++++++++++++-
 1 file changed, 99 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +99 -2
index 5df1a608e566..9bbdb78d3315 100644
@@ -29,6 +29,7 @@
 #include <linux/phy.h>
 #include <linux/slab.h>
 
+#include "dwxgmac2.h"
 #include "stmmac.h"
 
 #define MII_BUSY 0x00000001
@@ -39,6 +40,96 @@
 #define MII_GMAC4_WRITE			(1 << MII_GMAC4_GOC_SHIFT)
 #define MII_GMAC4_READ			(3 << MII_GMAC4_GOC_SHIFT)
 
+/* XGMAC defines */
+#define MII_XGMAC_SADDR			BIT(18)
+#define MII_XGMAC_CMD_SHIFT		16
+#define MII_XGMAC_WRITE			(1 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_READ			(3 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_BUSY			BIT(22)
+
+static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
+{
+	struct net_device *ndev = bus->priv;
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	unsigned int mii_address = priv->hw->mii.addr;
+	unsigned int mii_data = priv->hw->mii.data;
+	u32 tmp, addr, value = MII_XGMAC_BUSY;
+
+	if (phyreg & MII_ADDR_C45) {
+		return -EOPNOTSUPP;
+	} else {
+		if (phyaddr >= 4)
+			return -ENODEV;
+
+		/* Set port as Clause 22 */
+		tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
+		tmp |= BIT(phyaddr);
+		writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
+
+		addr = (phyaddr << 16) | (phyreg & 0x1f);
+	}
+
+	value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+		& priv->hw->mii.clk_csr_mask;
+	value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
+
+	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+			       !(tmp & MII_XGMAC_BUSY), 100, 10000))
+		return -EBUSY;
+
+	writel(addr, priv->ioaddr + mii_address);
+	writel(value, priv->ioaddr + mii_data);
+
+	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+			       !(tmp & MII_XGMAC_BUSY), 100, 10000))
+		return -EBUSY;
+
+	/* Read the data from the MII data register */
+	return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
+}
+
+static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
+				    int phyreg, u16 phydata)
+{
+	struct net_device *ndev = bus->priv;
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	unsigned int mii_address = priv->hw->mii.addr;
+	unsigned int mii_data = priv->hw->mii.data;
+	u32 addr, tmp, value = MII_XGMAC_BUSY;
+
+	if (phyreg & MII_ADDR_C45) {
+		return -EOPNOTSUPP;
+	} else {
+		if (phyaddr >= 4)
+			return -ENODEV;
+
+		/* Set port as Clause 22 */
+		tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
+		tmp |= BIT(phyaddr);
+		writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
+
+		addr = (phyaddr << 16) | (phyreg & 0x1f);
+	}
+
+	value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+		& priv->hw->mii.clk_csr_mask;
+	value |= phydata | MII_XGMAC_SADDR;
+	value |= MII_XGMAC_WRITE;
+
+	/* Wait until any existing MII operation is complete */
+	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+			       !(tmp & MII_XGMAC_BUSY), 100, 10000))
+		return -EBUSY;
+
+	/* Set the MII address register to write */
+	writel(addr, priv->ioaddr + mii_address);
+	writel(value, priv->ioaddr + mii_data);
+
+	/* Wait until any existing MII operation is complete */
+	return readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+				  !(tmp & MII_XGMAC_BUSY), 100, 10000);
+}
+
 /**
  * stmmac_mdio_read
  * @bus: points to the mii_bus structure
@@ -223,8 +314,14 @@ int stmmac_mdio_register(struct net_device *ndev)
 #endif
 
 	new_bus->name = "stmmac";
-	new_bus->read = &stmmac_mdio_read;
-	new_bus->write = &stmmac_mdio_write;
+
+	if (priv->plat->has_xgmac) {
+		new_bus->read = &stmmac_xgmac2_mdio_read;
+		new_bus->write = &stmmac_xgmac2_mdio_write;
+	} else {
+		new_bus->read = &stmmac_mdio_read;
+		new_bus->write = &stmmac_mdio_write;
+	}
 
 	new_bus->reset = &stmmac_mdio_reset;
 	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
Signature · 1 line
2.7.4
#6 lore raw

Re: [PATCH v2 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

Quoted 49 lines · Jose Abreu

Add the MDIO related funcionalities for the new IP block XGMAC2.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
Cc Andrew Lunn <[email protected]>

---
Changes from v1:
- Remove C45 support (Andrew)
- Add define for bits (Andrew)
- Remove uneeded cast (Andrew)
- Use different callbacks instead of if's (Andrew)

---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 101 +++++++++++++++++++++-
 1 file changed, 99 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +16 -0
index 5df1a608e566..9bbdb78d3315 100644
@@ -29,6 +29,7 @@
 #include <linux/phy.h>
 #include <linux/slab.h>
 
+#include "dwxgmac2.h"
 #include "stmmac.h"
 
 #define MII_BUSY 0x00000001
@@ -39,6 +40,96 @@
 #define MII_GMAC4_WRITE			(1 << MII_GMAC4_GOC_SHIFT)
 #define MII_GMAC4_READ			(3 << MII_GMAC4_GOC_SHIFT)
 
+/* XGMAC defines */
+#define MII_XGMAC_SADDR			BIT(18)
+#define MII_XGMAC_CMD_SHIFT		16
+#define MII_XGMAC_WRITE			(1 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_READ			(3 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_BUSY			BIT(22)
+
+static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
+{
+	struct net_device *ndev = bus->priv;
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	unsigned int mii_address = priv->hw->mii.addr;
+	unsigned int mii_data = priv->hw->mii.data;
+	u32 tmp, addr, value = MII_XGMAC_BUSY;
+

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 67

Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +10 -0
+	if (phyreg & MII_ADDR_C45) {
+		return -EOPNOTSUPP;
+	} else {
+		if (phyaddr >= 4)
+			return -ENODEV;
+
+		/* Set port as Clause 22 */
+		tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
+		tmp |= BIT(phyaddr);
+		writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);

Hi Jose

Maybe put this into a helper? You do repeat it twice.

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 69

Quoted 2 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +2 -0
+
+		addr = (phyaddr << 16) | (phyreg & 0x1f);

You could use GENMASK(4, 0) here. That was the point i was trying to make earlier. But i actually find 0x1f, and 0xffff easier to read.

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 78

Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +9 -0
+	}
+
+	value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+		& priv->hw->mii.clk_csr_mask;
+	value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
+
+	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+			       !(tmp & MII_XGMAC_BUSY), 100, 10000))
+		return -EBUSY;

Probably you want to wait for the bus to be idle before you change the mode to C22. Some PHYs can do both C22 and C45, e.g. EEE registers can be in C45 space, while the rest are in C22.

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 89

Quoted 11 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +11 -0
+
+	writel(addr, priv->ioaddr + mii_address);
+	writel(value, priv->ioaddr + mii_data);
+
+	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+			       !(tmp & MII_XGMAC_BUSY), 100, 10000))
+		return -EBUSY;
+
+	/* Read the data from the MII data register */
+	return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
+}

Andrew

author
#7 lore raw

Re: [PATCH v2 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

Hi Andrew,

Quoted 62 lines · Andrew Lunn
Quoted 49 lines · Jose Abreu

Add the MDIO related funcionalities for the new IP block XGMAC2.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
Cc Andrew Lunn <[email protected]>

---
Changes from v1:
- Remove C45 support (Andrew)
- Add define for bits (Andrew)
- Remove uneeded cast (Andrew)
- Use different callbacks instead of if's (Andrew)

---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 101 +++++++++++++++++++++-
 1 file changed, 99 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +16 -0
index 5df1a608e566..9bbdb78d3315 100644
@@ -29,6 +29,7 @@
 #include <linux/phy.h>
 #include <linux/slab.h>
 
+#include "dwxgmac2.h"
 #include "stmmac.h"
 
 #define MII_BUSY 0x00000001
@@ -39,6 +40,96 @@
 #define MII_GMAC4_WRITE			(1 << MII_GMAC4_GOC_SHIFT)
 #define MII_GMAC4_READ			(3 << MII_GMAC4_GOC_SHIFT)
 
+/* XGMAC defines */
+#define MII_XGMAC_SADDR			BIT(18)
+#define MII_XGMAC_CMD_SHIFT		16
+#define MII_XGMAC_WRITE			(1 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_READ			(3 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_BUSY			BIT(22)
+
+static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
+{
+	struct net_device *ndev = bus->priv;
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	unsigned int mii_address = priv->hw->mii.addr;
+	unsigned int mii_data = priv->hw->mii.data;
+	u32 tmp, addr, value = MII_XGMAC_BUSY;
+

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 67

Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +10 -0
+	if (phyreg & MII_ADDR_C45) {
+		return -EOPNOTSUPP;
+	} else {
+		if (phyaddr >= 4)
+			return -ENODEV;
+
+		/* Set port as Clause 22 */
+		tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
+		tmp |= BIT(phyaddr);
+		writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);

Hi Jose

Quoted 1 line

Maybe put this into a helper? You do repeat it twice.

Yes, makes sense.

Quoted 5 lines

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 69

Quoted 3 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +2 -0
+
+		addr = (phyaddr << 16) | (phyreg & 0x1f);

You could use GENMASK(4, 0) here. That was the point i was trying to make earlier. But i actually find 0x1f, and 0xffff easier to read.

Less typing :D

Quoted 13 lines

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 78

Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +9 -0
+	}
+
+	value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+		& priv->hw->mii.clk_csr_mask;
+	value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
+
+	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+			       !(tmp & MII_XGMAC_BUSY), 100, 10000))
+		return -EBUSY;

Probably you want to wait for the bus to be idle before you change the mode to C22. Some PHYs can do both C22 and C45, e.g. EEE registers can be in C45 space, while the rest are in C22.

Ok but I can't test C45 right now so maybe leave that change to when I can test it ?

Thanks and Best Regards,
Jose Miguel Abreu

Quoted 13 lines

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 89

Quoted 12 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +11 -0
+
+	writel(addr, priv->ioaddr + mii_address);
+	writel(value, priv->ioaddr + mii_data);
+
+	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+			       !(tmp & MII_XGMAC_BUSY), 100, 10000))
+		return -EBUSY;
+
+	/* Read the data from the MII data register */
+	return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
+}

Andrew

#8 lore raw

Re: [PATCH v2 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

Quoted 6 lines
Quoted 3 lines

Probably you want to wait for the bus to be idle before you change the mode to C22. Some PHYs can do both C22 and C45, e.g. EEE registers can be in C45 space, while the rest are in C22.

Ok but I can't test C45 right now so maybe leave that change to when I can test it ?

I would fix this now. It probably cannot cause issues now, but it is wrong. You are going to have to fix it some time, so why not now?

Andrew

author
#9 lore raw

PATCH v2 6/9 net: stmmac: Add PTP support for XGMAC2

In reply to Jose Abreu

XGMAC2 uses the same engine of timestamping as GMAC4. Let's use the same callbacks.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
---
 drivers/net/ethernet/stmicro/stmmac/hwif.c       | 4 ++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 6 ++++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)
drivers/net/ethernet/stmicro/stmmac/hwif.c +2 -2
index 4b4ba1c8bad5..357309a6d6a5 100644
@@ -193,13 +193,13 @@ static const struct stmmac_hwif_entry {
 		.xgmac = true,
 		.min_id = DWXGMAC_CORE_2_10,
 		.regs = {
-			.ptp_off = 0,
+			.ptp_off = PTP_XGMAC_OFFSET,
 			.mmc_off = 0,
 		},
 		.desc = &dwxgmac210_desc_ops,
 		.dma = &dwxgmac210_dma_ops,
 		.mac = &dwxgmac210_ops,
-		.hwtimestamp = NULL,
+		.hwtimestamp = &stmmac_ptp,
 		.mode = NULL,
 		.tc = NULL,
 		.setup = dwxgmac2_setup,
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +4 -2
index 0cb0e39a2be9..2293e21f789f 100644
@@ -71,6 +71,9 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
 	u32 sec, nsec;
 	u32 quotient, reminder;
 	int neg_adj = 0;
+	bool xmac;
+
+	xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
 	if (delta < 0) {
 		neg_adj = 1;
@@ -82,8 +85,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
 	nsec = reminder;
 
 	spin_lock_irqsave(&priv->ptp_lock, flags);
-	stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj,
-			priv->plat->has_gmac4);
+	stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
 	spin_unlock_irqrestore(&priv->ptp_lock, flags);
 
 	return 0;
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h +1 -0
index f4b31d69f60e..ecccf895fd7e 100644
@@ -21,6 +21,7 @@
 #ifndef	__STMMAC_PTP_H__
 #define	__STMMAC_PTP_H__
 
+#define PTP_XGMAC_OFFSET	0xd00
 #define	PTP_GMAC4_OFFSET	0xb00
 #define	PTP_GMAC3_X_OFFSET	0x700
 
Signature · 1 line
2.7.4
author
#10 lore raw

PATCH v2 7/9 net: stmmac: Integrate XGMAC into main driver flow

In reply to Jose Abreu

Now that we have all the XGMAC related callbacks, lets start integrating this IP block into main driver.

Also, we corrected the initialization flow to only start DMA after setting descriptors length.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
Cc Andrew Lunn <[email protected]>

---
Changes from v1:
- Correct flow of initialization
- Remove 2.5G/10G support (Andrew)

---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 ++++++++++++++++-------
 1 file changed, 48 insertions(+), 19 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +48 -19
index 9d104a05044d..ff1ffb46198a 100644
@@ -51,6 +51,7 @@
 #include <linux/reset.h>
 #include <linux/of_mdio.h>
 #include "dwmac1000.h"
+#include "dwxgmac2.h"
 #include "hwif.h"
 
 #define	STMMAC_ALIGN(x)		__ALIGN_KERNEL(x, SMP_CACHE_BYTES)
@@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
 		else
 			priv->clk_csr = 0;
 	}
+
+	if (priv->plat->has_xgmac) {
+		if (clk_rate > 400000000)
+			priv->clk_csr = 0x5;
+		else if (clk_rate > 350000000)
+			priv->clk_csr = 0x4;
+		else if (clk_rate > 300000000)
+			priv->clk_csr = 0x3;
+		else if (clk_rate > 250000000)
+			priv->clk_csr = 0x2;
+		else if (clk_rate > 150000000)
+			priv->clk_csr = 0x1;
+		else
+			priv->clk_csr = 0x0;
+	}
 }
 
 static void print_pkt(unsigned char *buf, int len)
@@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
 	if (!priv->hwts_rx_en)
 		return;
 	/* For GMAC4, the valid timestamp is from CTX next desc. */
-	if (priv->plat->has_gmac4)
+	if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
 		desc = np;
 
 	/* Check if timestamp is available */
@@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
 	u32 ts_event_en = 0;
 	u32 value = 0;
 	u32 sec_inc;
+	bool xmac;
+
+	xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
 	if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
 		netdev_alert(priv->dev, "No support for HW time stamping\n");
@@ -575,7 +594,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
 			/* PTP v1, UDP, any kind of event packet */
 			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
 			/* take time stamp for all event messages */
-			if (priv->plat->has_gmac4)
+			if (xmac)
 				snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
 			else
 				snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -610,7 +629,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
 			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
 			ptp_v2 = PTP_TCR_TSVER2ENA;
 			/* take time stamp for all event messages */
-			if (priv->plat->has_gmac4)
+			if (xmac)
 				snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
 			else
 				snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
 			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
 			ptp_v2 = PTP_TCR_TSVER2ENA;
 			/* take time stamp for all event messages */
-			if (priv->plat->has_gmac4)
+			if (xmac)
 				snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
 			else
 				snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
 		/* program Sub Second Increment reg */
 		stmmac_config_sub_second_increment(priv,
 				priv->ptpaddr, priv->plat->clk_ptp_rate,
-				priv->plat->has_gmac4, &sec_inc);
+				xmac, &sec_inc);
 		temp = div_u64(1000000000ULL, sec_inc);
 
 		/* Store sub second increment and flags for later use */
@@ -755,12 +774,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
  */
 static int stmmac_init_ptp(struct stmmac_priv *priv)
 {
+	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
+
 	if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
 		return -EOPNOTSUPP;
 
 	priv->adv_ts = 0;
-	/* Check if adv_ts can be enabled for dwmac 4.x core */
-	if (priv->plat->has_gmac4 && priv->dma_cap.atime_stamp)
+	/* Check if adv_ts can be enabled for dwmac 4.x / xgmac core */
+	if (xmac && priv->dma_cap.atime_stamp)
 		priv->adv_ts = 1;
 	/* Dwmac 3.x core with extend_desc can support adv_ts */
 	else if (priv->extend_desc && priv->dma_cap.atime_stamp)
@@ -2173,6 +2194,12 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
 		return ret;
 	}
 
+	/* DMA Configuration */
+	stmmac_dma_init(priv, priv->ioaddr, priv->plat->dma_cfg, atds);
+
+	if (priv->plat->axi)
+		stmmac_axi(priv, priv->ioaddr, priv->plat->axi);
+
 	/* DMA RX Channel Configuration */
 	for (chan = 0; chan < rx_channels_count; chan++) {
 		rx_q = &priv->rx_queue[chan];
@@ -2203,12 +2230,6 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
 	for (chan = 0; chan < dma_csr_ch; chan++)
 		stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
 
-	/* DMA Configuration */
-	stmmac_dma_init(priv, priv->ioaddr, priv->plat->dma_cfg, atds);
-
-	if (priv->plat->axi)
-		stmmac_axi(priv, priv->ioaddr, priv->plat->axi);
-
 	return ret;
 }
 
@@ -2526,9 +2547,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 		netdev_warn(priv->dev, "%s: failed debugFS registration\n",
 			    __func__);
 #endif
-	/* Start the ball rolling... */
-	stmmac_start_all_dma(priv);
-
 	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
 
 	if (priv->use_riwt) {
@@ -2549,6 +2567,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 			stmmac_enable_tso(priv, priv->ioaddr, 1, chan);
 	}
 
+	/* Start the ball rolling... */
+	stmmac_start_all_dma(priv);
+
 	return 0;
 }
 
@@ -3305,6 +3326,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 	int coe = priv->hw->rx_csum;
 	unsigned int next_entry;
 	unsigned int count = 0;
+	bool xmac;
+
+	xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
 	if (netif_msg_rx_status(priv)) {
 		void *rx_head;
@@ -3406,7 +3430,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 			 * in case of GMAC4 because it needs
 			 * to refill the used descriptors, always.
 			 */
-			if (unlikely(!priv->plat->has_gmac4 &&
+			if (unlikely(!xmac &&
 				     ((frame_len < priv->rx_copybreak) ||
 				     stmmac_rx_threshold_count(rx_q)))) {
 				skb = netdev_alloc_skb_ip_align(priv->dev,
@@ -3642,7 +3666,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
 	u32 tx_cnt = priv->plat->tx_queues_to_use;
 	u32 queues_count;
 	u32 queue;
+	bool xmac;
 
+	xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 	queues_count = (rx_cnt > tx_cnt) ? rx_cnt : tx_cnt;
 
 	if (priv->irq_wake)
@@ -3661,7 +3687,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
 		return IRQ_HANDLED;
 
 	/* To handle GMAC own interrupts */
-	if ((priv->plat->has_gmac) || (priv->plat->has_gmac4)) {
+	if ((priv->plat->has_gmac) || xmac) {
 		int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats);
 		int mtl_status;
 
@@ -4269,6 +4295,8 @@ int stmmac_dvr_probe(struct device *device,
 	ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
 	if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00))
 		ndev->max_mtu = JUMBO_LEN;
+	else if (priv->plat->has_xgmac)
+		ndev->max_mtu = XGMAC_JUMBO_LEN;
 	else
 		ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
 	/* Will not overwrite ndev->max_mtu if plat->maxmtu > ndev->max_mtu
@@ -4290,7 +4318,8 @@ int stmmac_dvr_probe(struct device *device,
 	 * has to be disable and this can be done by passing the
 	 * riwt_off field from the platform.
 	 */
-	if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) {
+	if (((priv->synopsys_id >= DWMAC_CORE_3_50) ||
+	    (priv->plat->has_xgmac)) && (!priv->plat->riwt_off)) {
 		priv->use_riwt = 1;
 		dev_info(priv->device,
 			 "Enable RX Mitigation via HW Watchdog Timer\n");
Signature · 1 line
2.7.4
author
#11 lore raw

PATCH v2 8/9 net: stmmac: Add the bindings parsing for XGMAC2

In reply to Jose Abreu

Add the bindings parsing for XGMAC2 IP block.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c   | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++++
 2 files changed, 8 insertions(+)
drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c +2 -0
index 3304095c934c..fad503820e04 100644
@@ -78,6 +78,8 @@ static const struct of_device_id dwmac_generic_match[] = {
 	{ .compatible = "snps,dwmac-4.00"},
 	{ .compatible = "snps,dwmac-4.10a"},
 	{ .compatible = "snps,dwmac"},
+	{ .compatible = "snps,dwxgmac-2.10"},
+	{ .compatible = "snps,dwxgmac"},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, dwmac_generic_match);
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +6 -0
index 72da77b94ecd..3609c7b696c7 100644
@@ -486,6 +486,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
 		plat->force_sf_dma_mode = 1;
 	}
 
+	if (of_device_is_compatible(np, "snps,dwxgmac")) {
+		plat->has_xgmac = 1;
+		plat->pmt = 1;
+		plat->tso_en = of_property_read_bool(np, "snps,tso");
+	}
+
 	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
 			       GFP_KERNEL);
 	if (!dma_cfg) {
Signature · 1 line
2.7.4
author
#12 lore raw

PATCH v2 9/9 dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.

In reply to Jose Abreu

Adds the documentation for XGMAC2 DT bindings.

Cc David S. Miller <[email protected]>
Cc Joao Pinto <[email protected]>
Cc Giuseppe Cavallaro <[email protected]>
Cc Alexandre Torgue <[email protected]>
Cc Sergei Shtylyov <[email protected]>
Cc Rob Herring <[email protected]>

---
Changes from v1:
- Correct header, now we also support 2.5/10G.
- Add missing '>' (Sergei)

---
 Documentation/devicetree/bindings/net/stmmac.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/net/stmmac.txt +3 -2
index 3a28a5d8857d..a32fd590ce8f 100644
@@ -1,7 +1,8 @@
-* STMicroelectronics 10/100/1000 Ethernet driver (GMAC)
+* STMicroelectronics 10/100/1000/2500/10000 Ethernet driver (GMAC/XGMAC)
 
 Required properties:
-- compatible: Should be "snps,dwmac-<ip_version>", "snps,dwmac"
+- compatible: Should be "snps,dwmac-<ip_version>", "snps,dwmac" or
+	"snps,dwxgmac-<ip_version>", "snps,dwxgmac".
 	For backwards compatibility: "st,spear600-gmac" is also supported.
 - reg: Address and length of the register set for the device
 - interrupt-parent: Should be the phandle for the interrupt controller
Signature · 1 line
2.7.4