public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Krzysztof Kozlowski <krzk@kernel.org>
To: Srinivas Neeli <srinivas.neeli@amd.com>,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, michal.simek@amd.com,
	robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	richardcochran@gmail.com
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	git@amd.com
Subject: Re: [RFC PATCH 2/8] net: xilinx: tsn: Introduce TSN core driver skeleton
Date: Thu, 19 Feb 2026 08:32:25 +0100	[thread overview]
Message-ID: <8dde3889-e51d-4e20-926b-7cdbdef3ddf7@kernel.org> (raw)
In-Reply-To: <20260219054911.2017362-3-srinivas.neeli@amd.com>

On 19/02/2026 06:49, Srinivas Neeli wrote:
> Introduce the initial skeleton for the AMD/Xilinx Time Sensitive
> Networking (TSN) Ethernet IP driver. Adds the Kconfig entry
> (CONFIG_XILINX_TSN), updates the Xilinx Ethernet Makefile,
> and provides the base source file focused on device tree
> parsing and clock acquisition.
> 
> Signed-off-by: Srinivas Neeli <srinivas.neeli@amd.com>
> ---
>  drivers/net/ethernet/xilinx/Kconfig           |   1 +
>  drivers/net/ethernet/xilinx/Makefile          |   1 +
>  drivers/net/ethernet/xilinx/tsn/Kconfig       |  14 ++
>  drivers/net/ethernet/xilinx/tsn/Makefile      |   2 +
>  drivers/net/ethernet/xilinx/tsn/xilinx_tsn.h  |  60 +++++
>  .../net/ethernet/xilinx/tsn/xilinx_tsn_main.c | 218 ++++++++++++++++++
>  6 files changed, 296 insertions(+)
>  create mode 100644 drivers/net/ethernet/xilinx/tsn/Kconfig
>  create mode 100644 drivers/net/ethernet/xilinx/tsn/Makefile
>  create mode 100644 drivers/net/ethernet/xilinx/tsn/xilinx_tsn.h
>  create mode 100644 drivers/net/ethernet/xilinx/tsn/xilinx_tsn_main.c
> 
> diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig
> index 7502214cc7d5..c6d704c8d3d4 100644
> --- a/drivers/net/ethernet/xilinx/Kconfig
> +++ b/drivers/net/ethernet/xilinx/Kconfig
> @@ -41,4 +41,5 @@ config XILINX_LL_TEMAC
>  	  This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
>  	  core used in Xilinx Spartan and Virtex FPGAs
>  
> +source "drivers/net/ethernet/xilinx/tsn/Kconfig"
>  endif # NET_VENDOR_XILINX
> diff --git a/drivers/net/ethernet/xilinx/Makefile b/drivers/net/ethernet/xilinx/Makefile
> index 7d7dc1771423..66dab012650b 100644
> --- a/drivers/net/ethernet/xilinx/Makefile
> +++ b/drivers/net/ethernet/xilinx/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
>  obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
>  xilinx_emac-objs := xilinx_axienet_main.o xilinx_axienet_mdio.o
>  obj-$(CONFIG_XILINX_AXI_EMAC) += xilinx_emac.o
> +obj-$(CONFIG_XILINX_TSN) += tsn/
> diff --git a/drivers/net/ethernet/xilinx/tsn/Kconfig b/drivers/net/ethernet/xilinx/tsn/Kconfig
> new file mode 100644
> index 000000000000..53734842700b
> --- /dev/null
> +++ b/drivers/net/ethernet/xilinx/tsn/Kconfig
> @@ -0,0 +1,14 @@
> +config XILINX_TSN
> +	tristate "Xilinx TSN Ethernet driver"
> +	depends on OF && HAS_IOMEM

No ARCH_XILINX?

> +	select PHYLIB
> +	select NET_DEVLINK
> +	select NET_DEV_STATS
> +	help
> +	  This driver supports the Xilinx Time-Sensitive Networking (TSN)
> +	  Ethernet IP, which includes multiple Ethernet MACs, a TSN switch,
> +	  and an endpoint block. It provides support for scheduling,
> +	  traffic shaping, and time synchronization to meet real-time
> +	  requirements of industrial Ethernet applications.
> +


...


> +
> +/*
> + * Helper to parse TX queue config subnode referenced by
> + * xlnx,tsn-tx-config. This version enumerates child nodes in order and
> + * assigns DMA channels sequentially (queue0 == first child, etc.)
> + */
> +static int tsn_parse_tx_queue_config(struct device *dev, struct tsn_priv *common,
> +				     struct device_node *txcfg_np)
> +{
> +	struct device_node *qnode;
> +	unsigned int queue = 0;
> +	int ret = 0;
> +
> +	for_each_available_child_of_node(txcfg_np, qnode) {
> +		u32 chan;
> +
> +		if (queue >= common->num_tx_queues) {
> +			dev_err(dev, "tx-config: extra child nodes beyond %u ignored\n",
> +				common->num_tx_queues);
> +			of_node_put(qnode);

Use scoped loop.

> +			return -EINVAL;
> +		}
> +
> +		ret = of_property_read_u32(qnode, "xlnx,dma-channel-num", &chan);
> +		if (ret) {
> +			dev_err(dev, "tx-config: Q%u missing xlnx,dma-channel-num\n", queue);
> +			of_node_put(qnode);
> +			return ret;
> +		}
> +
> +		if (chan > TSN_DMA_MAX_TX_CH) {
> +			dev_err(dev, "tx-config: Q%u channel %u exceeds max %lu\n",
> +				queue, chan, TSN_DMA_MAX_TX_CH);
> +			of_node_put(qnode);
> +			return -EINVAL;
> +		}
> +		common->tx_dma_chan_map[queue++] = chan;
> +	}
> +
> +	if (queue != common->num_tx_queues) {
> +		dev_err(dev, "tx-config: described %u queues but expected %u\n",
> +			queue, common->num_tx_queues);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * tsn_parse_device_tree - Parse device tree configuration for TSN device
> + * @pdev: Platform device pointer
> + *
> + * Return: 0 on success, negative error code on failure
> + */
> +static int tsn_parse_device_tree(struct platform_device *pdev)
> +{
> +	struct tsn_priv *common = platform_get_drvdata(pdev);
> +	struct device_node *txcfg_np = NULL;
> +	struct device *dev = &pdev->dev;
> +	int i, ret;
> +
> +	/* Read number of priorities */
> +	ret = of_property_read_u32(dev->of_node, "xlnx,num-priorities", &common->num_priorities);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to get xlnx,num-priorities\n");
> +
> +	if (common->num_priorities < TSN_MIN_PRIORITIES ||
> +	    common->num_priorities > TSN_MAX_PRIORITIES)
> +		return dev_err_probe(dev, -EINVAL, "Invalid xlnx,num-priorities (%u)\n",
> +				     common->num_priorities);
> +
> +	/* Count TX and RX queues from dma-names property */
> +	ret = of_property_count_strings(dev->of_node, "dma-names");
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Failed to get dma-names\n");
> +
> +	common->num_tx_queues = 0;
> +	common->num_rx_queues = 0;
> +
> +	for (i = 0; i < ret; i++) {
> +		const char *dma_name;
> +
> +		if (of_property_read_string_index(dev->of_node, "dma-names", i, &dma_name))
> +			continue;
> +
> +		if (strncmp(dma_name, "tx_chan", 7) == 0)
> +			common->num_tx_queues++;
> +		else if (strncmp(dma_name, "rx_chan", 7) == 0)
> +			common->num_rx_queues++;
> +	}
> +
> +	if (!common->num_tx_queues || common->num_tx_queues > TSN_MAX_TX_QUEUE)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "Invalid TX queue count (%u, max %u)\n",
> +				     common->num_tx_queues, TSN_MAX_TX_QUEUE);
> +
> +	if (!common->num_rx_queues)
> +		return dev_err_probe(dev, -EINVAL, "No RX DMA channels found\n");
> +
> +	/* Setup clock IDs */
> +	for (i = 0; i < TSN_NUM_CLOCKS; i++)
> +		common->clks[i].id = tsn_clk_names[i];
> +
> +	/* Get all clocks */
> +	ret = devm_clk_bulk_get(dev, TSN_NUM_CLOCKS, common->clks);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to get clocks\n");
> +
> +	/* Enable clocks */
> +	ret = clk_bulk_prepare_enable(TSN_NUM_CLOCKS, common->clks);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to enable clocks\n");
> +
> +	for (i = 0; i < TSN_MAX_TX_QUEUE; i++)
> +		common->tx_dma_chan_map[i] = TSN_DMA_CH_INVALID;
> +
> +	txcfg_np = of_parse_phandle(dev->of_node, "xlnx,tsn-tx-config", 0);
> +	if (txcfg_np) {
> +		ret = tsn_parse_tx_queue_config(dev, common, txcfg_np);
> +		of_node_put(txcfg_np);
> +		if (ret)
> +			goto err_disable_clks;
> +	}
> +
> +	return 0;
> +
> +err_disable_clks:
> +	clk_bulk_disable_unprepare(TSN_NUM_CLOCKS, common->clks);
> +	return ret;
> +}
> +
> +/**
> + * tsn_ip_probe - Probe TSN IP core device

Nooo...


> + * @pdev: Platform device pointer
> + *
> + * Return: 0 on success, negative error code on failure
> + */
> +static int tsn_ip_probe(struct platform_device *pdev)
> +{
> +	struct tsn_priv *common;
> +	int ret;
> +
> +	common = devm_kzalloc(&pdev->dev, sizeof(*common), GFP_KERNEL);
> +	if (!common)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, common);
> +	common->pdev = pdev;
> +	common->dev = &pdev->dev;
> +
> +	/* Initialize synchronization primitives */
> +	spin_lock_init(&common->tx_lock);
> +	spin_lock_init(&common->rx_lock);
> +	mutex_init(&common->mdio_lock);
> +
> +	common->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!common->res)
> +		return -ENODEV;
> +	common->regs_start = common->res->start;
> +	common->regs = devm_ioremap_resource(&pdev->dev, common->res);
> +	if (IS_ERR(common->regs))
> +		return PTR_ERR(common->regs);
> +
> +	ret = tsn_parse_device_tree(pdev);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +/**
> + * tsn_ip_remove - Remove TSN IP core device
> + * @pdev: Platform device pointer

Pointless comment. Can it be anything else than what you wrote? Why are
you adding comments to standard boilerplate calls?

> + */
> +static void tsn_ip_remove(struct platform_device *pdev)
> +{
> +	struct tsn_priv *common = platform_get_drvdata(pdev);
> +
> +	clk_bulk_disable_unprepare(TSN_NUM_CLOCKS, common->clks);
> +}
> +
> +static const struct of_device_id tsn_of_match[] = {
> +	{ .compatible = "xlnx,tsn-endpoint-ethernet-mac-3.0", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, tsn_of_match);
> +
> +static struct platform_driver tsn_driver = {
> +	.probe = tsn_ip_probe,
> +	.remove = tsn_ip_remove,
> +	.driver = {
> +		.name = "xilinx-tsn",
> +		.of_match_table = tsn_of_match,
> +	},
> +};
> +module_platform_driver(tsn_driver);
> +
> +MODULE_AUTHOR("Neeli Srinivas <srinivas.neeli@amd.com>");
> +MODULE_DESCRIPTION("Time Sensitive Networking (TSN) Ethernet MAC driver");
> +MODULE_LICENSE("GPL");


Best regards,
Krzysztof

  reply	other threads:[~2026-02-19  7:32 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-19  5:49 [RFC PATCH 0/8] xilinx: tsn: Add TSN Endpoint Ethernet MAC driver support Srinivas Neeli
2026-02-19  5:49 ` [RFC PATCH 1/8] dt-bindings: net: Add TSN Endpoint Ethernet MAC support Srinivas Neeli
2026-02-19 16:53   ` Andrew Lunn
2026-02-20 13:03     ` Neeli, Srinivas
2026-02-20 13:39       ` Andrew Lunn
2026-02-24 11:08         ` Neeli, Srinivas
2026-02-19  5:49 ` [RFC PATCH 2/8] net: xilinx: tsn: Introduce TSN core driver skeleton Srinivas Neeli
2026-02-19  7:32   ` Krzysztof Kozlowski [this message]
2026-02-19  5:49 ` [RFC PATCH 3/8] net: xilinx: tsn: Add TSN endpoint and MCDMA support Srinivas Neeli
2026-02-19  5:49 ` [RFC PATCH 4/8] xilinx: tsn: Add Ethernet MAC (EMAC) and MDIO support to the TSN driver Srinivas Neeli
2026-02-19 17:05   ` Andrew Lunn
2026-02-20 13:08     ` Neeli, Srinivas
2026-02-20 15:03       ` Andrew Lunn
2026-02-24 11:11         ` Neeli, Srinivas
2026-02-20 15:12   ` Andrew Lunn
2026-02-24 11:15     ` Neeli, Srinivas
2026-02-19  5:49 ` [RFC PATCH 5/8] net: xilinx: tsn: Add TSN switch support with port state and frame filter control Srinivas Neeli
2026-02-19  5:49 ` [RFC PATCH 6/8] dt-bindings: net: Add PTP interrupt support Srinivas Neeli
2026-02-20 15:17   ` Andrew Lunn
2026-02-19  5:49 ` [RFC PATCH 7/8] net: xilinx: tsn: Add PTP hardware clock (PHC) and timer support Srinivas Neeli
2026-02-19  5:49 ` [RFC PATCH 8/8] net: xilinx: tsn: Add PTP packet transmission support Srinivas Neeli
2026-02-19  7:34 ` [RFC PATCH 0/8] xilinx: tsn: Add TSN Endpoint Ethernet MAC driver support Krzysztof Kozlowski
2026-02-19 16:42 ` Andrew Lunn
2026-02-20 12:59   ` Neeli, Srinivas
2026-02-20 13:36     ` Andrew Lunn
2026-03-05 11:46       ` Neeli, Srinivas
2026-03-26 10:11         ` Neeli, Srinivas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8dde3889-e51d-4e20-926b-7cdbdef3ddf7@kernel.org \
    --to=krzk@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=conor+dt@kernel.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=git@amd.com \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michal.simek@amd.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=richardcochran@gmail.com \
    --cc=robh@kernel.org \
    --cc=srinivas.neeli@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox