[PATCH 10/20] net: dsa: xilinx: add skeleton driver for TSN switch

Nagadheeraj Rottela nagadheeraj.rottela at amd.com
Fri Aug 7 03:44:21 PDT 2026


Add a skeleton DSA driver for the three-port switch block of the
AMD/Xilinx TSN Endpoint Ethernet MAC IP. It binds
"xlnx,tsn-switch", maps the switch fabric and two per-MAC register
windows ("switch", "mac1", "mac2"), and registers a dsa_switch with
num_ports = 3. Port 0 is the CPU port, wired internally to the
endpoint MAC. Ports 1 and 2 are the external user ports backed by
MAC1 and MAC2.

At this stage only get_tag_protocol is wired. setup and teardown
are stubs. MDIO, phylink, frame filtering, and PTP follow in
subsequent patches.

Signed-off-by: Nagadheeraj Rottela <nagadheeraj.rottela at amd.com>
---
 MAINTAINERS                         |   1 +
 drivers/net/dsa/Kconfig             |   2 +
 drivers/net/dsa/Makefile            |   1 +
 drivers/net/dsa/xilinx/Kconfig      |  11 +++
 drivers/net/dsa/xilinx/Makefile     |   3 +
 drivers/net/dsa/xilinx/xilinx_tsn.c | 126 ++++++++++++++++++++++++++++
 drivers/net/dsa/xilinx/xilinx_tsn.h |  31 +++++++
 7 files changed, 175 insertions(+)
 create mode 100644 drivers/net/dsa/xilinx/Kconfig
 create mode 100644 drivers/net/dsa/xilinx/Makefile
 create mode 100644 drivers/net/dsa/xilinx/xilinx_tsn.c
 create mode 100644 drivers/net/dsa/xilinx/xilinx_tsn.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6fbe83fb3953..0e91cb2a307d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29613,6 +29613,7 @@ M:	Srinivas Neeli <srinivas.neeli at amd.com>
 L:	netdev at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/net/xlnx,tsn-endpoint-ethernet-mac.yaml
+F:	drivers/net/dsa/xilinx/
 F:	drivers/net/ethernet/xilinx/tsn/
 F:	net/dsa/tag_xlnx_tsn.c
 
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 4ab567c5bbaf..1404a77579f1 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -84,6 +84,8 @@ source "drivers/net/dsa/qca/Kconfig"
 
 source "drivers/net/dsa/sja1105/Kconfig"
 
+source "drivers/net/dsa/xilinx/Kconfig"
+
 source "drivers/net/dsa/xrs700x/Kconfig"
 
 source "drivers/net/dsa/realtek/Kconfig"
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index d2975badffc0..75b8449b575e 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -26,4 +26,5 @@ obj-y				+= ocelot/
 obj-y				+= qca/
 obj-y				+= realtek/
 obj-y				+= sja1105/
+obj-y				+= xilinx/
 obj-y				+= xrs700x/
diff --git a/drivers/net/dsa/xilinx/Kconfig b/drivers/net/dsa/xilinx/Kconfig
new file mode 100644
index 000000000000..0bd5efe8490b
--- /dev/null
+++ b/drivers/net/dsa/xilinx/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+config NET_DSA_XILINX_TSN
+	tristate "AMD/Xilinx TSN Endpoint Ethernet MAC switch support"
+	depends on OF && HAS_IOMEM
+	depends on NET_DSA
+	select NET_DSA_TAG_XLNX_TSN
+	help
+	  This enables DSA switch support for the three-port switch
+	  block of the AMD/Xilinx TSN Endpoint Ethernet MAC IP. Port 0
+	  is the CPU port, wired internally to the endpoint MAC; ports 1
+	  and 2 are external Ethernet ports backed by MAC1 and MAC2.
diff --git a/drivers/net/dsa/xilinx/Makefile b/drivers/net/dsa/xilinx/Makefile
new file mode 100644
index 000000000000..334f0f979276
--- /dev/null
+++ b/drivers/net/dsa/xilinx/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+obj-$(CONFIG_NET_DSA_XILINX_TSN) += xlnx_tsn_dsa.o
+xlnx_tsn_dsa-y := xilinx_tsn.o
diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/xilinx_tsn.c
new file mode 100644
index 000000000000..6b285c528724
--- /dev/null
+++ b/drivers/net/dsa/xilinx/xilinx_tsn.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <net/dsa.h>
+
+#include "xilinx_tsn.h"
+
+static enum dsa_tag_protocol xlnx_tsn_get_tag_protocol(struct dsa_switch *ds,
+						       int port,
+						       enum dsa_tag_protocol mp)
+{
+	return DSA_TAG_PROTO_XLNX_TSN;
+}
+
+static int xlnx_tsn_setup(struct dsa_switch *ds)
+{
+	return 0;
+}
+
+static void xlnx_tsn_teardown(struct dsa_switch *ds)
+{
+}
+
+static const struct dsa_switch_ops xlnx_tsn_switch_ops = {
+	.get_tag_protocol	= xlnx_tsn_get_tag_protocol,
+	.setup			= xlnx_tsn_setup,
+	.teardown		= xlnx_tsn_teardown,
+};
+
+static int xlnx_tsn_map_reg(struct platform_device *pdev, const char *name,
+			    void __iomem **out)
+{
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource_byname(pdev, name);
+	if (IS_ERR(base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(base),
+				     "failed to map %s reg window\n", name);
+
+	*out = base;
+	return 0;
+}
+
+static int xlnx_tsn_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct dsa_switch *ds;
+	struct xlnx_tsn *sw;
+	int ret;
+
+	sw = devm_kzalloc(dev, sizeof(*sw), GFP_KERNEL);
+	if (!sw)
+		return -ENOMEM;
+
+	sw->dev = dev;
+
+	ret = xlnx_tsn_map_reg(pdev, "switch", &sw->sw_base);
+	if (ret)
+		return ret;
+
+	ret = xlnx_tsn_map_reg(pdev, "mac1", &sw->mac_base[XLNX_TSN_PORT_MAC1]);
+	if (ret)
+		return ret;
+
+	ret = xlnx_tsn_map_reg(pdev, "mac2", &sw->mac_base[XLNX_TSN_PORT_MAC2]);
+	if (ret)
+		return ret;
+
+	ds = &sw->ds;
+	ds->dev = dev;
+	ds->num_ports = XLNX_TSN_NUM_PORTS;
+	ds->ops = &xlnx_tsn_switch_ops;
+	ds->priv = sw;
+
+	platform_set_drvdata(pdev, sw);
+
+	return dsa_register_switch(ds);
+}
+
+static void xlnx_tsn_remove(struct platform_device *pdev)
+{
+	struct xlnx_tsn *sw = platform_get_drvdata(pdev);
+
+	if (!sw)
+		return;
+
+	dsa_unregister_switch(&sw->ds);
+}
+
+static void xlnx_tsn_shutdown(struct platform_device *pdev)
+{
+	struct xlnx_tsn *sw = platform_get_drvdata(pdev);
+
+	if (!sw)
+		return;
+
+	dsa_switch_shutdown(&sw->ds);
+	platform_set_drvdata(pdev, NULL);
+}
+
+static const struct of_device_id xlnx_tsn_of_match[] = {
+	{ .compatible = "xlnx,tsn-switch" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xlnx_tsn_of_match);
+
+static struct platform_driver xlnx_tsn_driver = {
+	.driver = {
+		.name		= "xlnx-tsn-switch",
+		.of_match_table	= xlnx_tsn_of_match,
+	},
+	.probe		= xlnx_tsn_probe,
+	.remove		= xlnx_tsn_remove,
+	.shutdown	= xlnx_tsn_shutdown,
+};
+module_platform_driver(xlnx_tsn_driver);
+
+MODULE_AUTHOR("Nagadheeraj Rottela <nagadheeraj.rottela at amd.com>");
+MODULE_DESCRIPTION("AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.h b/drivers/net/dsa/xilinx/xilinx_tsn.h
new file mode 100644
index 000000000000..0f9af866bd18
--- /dev/null
+++ b/drivers/net/dsa/xilinx/xilinx_tsn.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * AMD/Xilinx TSN Endpoint Ethernet MAC DSA switch driver.
+ */
+#ifndef _XILINX_TSN_H
+#define _XILINX_TSN_H
+
+#include <linux/types.h>
+#include <net/dsa.h>
+
+#define XLNX_TSN_NUM_PORTS	3
+#define XLNX_TSN_CPU_PORT	0
+#define XLNX_TSN_PORT_MAC1	1
+#define XLNX_TSN_PORT_MAC2	2
+
+/**
+ * struct xlnx_tsn - per-IP switch state
+ * @ds: DSA switch
+ * @dev: backing device
+ * @sw_base: switch fabric register window
+ * @mac_base: per-MAC register windows, indexed by user-port number
+ *	      (index 0 unused; MAC1 at [1], MAC2 at [2])
+ */
+struct xlnx_tsn {
+	struct dsa_switch ds;
+	struct device *dev;
+	void __iomem *sw_base;
+	void __iomem *mac_base[XLNX_TSN_NUM_PORTS];
+};
+
+#endif /* _XILINX_TSN_H */
-- 
2.34.1




More information about the linux-arm-kernel mailing list