[PATCH v4 2/6] drivers: net: add a DSA sandbox driver

Priyanka Jain (OSS) priyanka.jain at oss.nxp.com
Fri Jul 24 06:03:26 CEST 2020


>-----Original Message-----
>From: U-Boot <u-boot-bounces at lists.denx.de> On Behalf Of Claudiu Manoil
>Sent: Tuesday, May 5, 2020 11:13 PM
>To: u-boot at lists.denx.de
>Cc: joe.hershberger at ni.com; Alexandru Marginean
><alexandru.marginean at nxp.com>; Vladimir Oltean
><vladimir.oltean at nxp.com>
>Subject: [PATCH v4 2/6] drivers: net: add a DSA sandbox driver
>
>From: Alex Marginean <alexandru.marginean at nxp.com>
>
>The DSA sandbox driver is used for DSA unit testing.  It implements a simple 4
>port switch that uses a very simple tag to identify the ports.
>The DSA driver comes paired with an Ethernet driver that loops packets back
>and can selectively filter traffic on DSA switch ports.
>
>Signed-off-by: Alex Marginean <alexandru.marginean at nxp.com>
>Signed-off-by: Claudiu Manoil <claudiu.manoil at nxp.com>
>---
> drivers/net/Kconfig       |   8 ++
> drivers/net/Makefile      |   1 +
> drivers/net/dsa_sandbox.c | 272
>++++++++++++++++++++++++++++++++++++++
> 3 files changed, 281 insertions(+)
> create mode 100644 drivers/net/dsa_sandbox.c
>
>diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index
>863314284b..f982f18d26 100644
>--- a/drivers/net/Kconfig
>+++ b/drivers/net/Kconfig
>@@ -70,6 +70,14 @@ config MDIO_MUX_SANDBOX
>
> 	  This driver is used for testing in test/dm/mdio.c
>
>+config DSA_SANDBOX
>+	depends on DM_DSA && SANDBOX
>+	default y
>+	bool "Sandbox: Mocked DSA driver"
>+	help
>+	  This driver implements a dummy switch and a dummy Ethernet
>device used
>+	  to test DSA class code.
>+
> menuconfig NETDEVICES
> 	bool "Network device support"
> 	depends on NET
>diff --git a/drivers/net/Makefile b/drivers/net/Makefile index
>6e0a68834d..f840b39893 100644
>--- a/drivers/net/Makefile
>+++ b/drivers/net/Makefile
>@@ -83,3 +83,4 @@ obj-y += mscc_eswitch/
> obj-$(CONFIG_HIGMACV300_ETH) += higmacv300.o
> obj-$(CONFIG_MDIO_SANDBOX) += mdio_sandbox.o
> obj-$(CONFIG_FSL_ENETC) += fsl_enetc.o fsl_enetc_mdio.o
>+obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o
>diff --git a/drivers/net/dsa_sandbox.c b/drivers/net/dsa_sandbox.c new file
>mode 100644 index 0000000000..7475478668
>--- /dev/null
>+++ b/drivers/net/dsa_sandbox.c
>@@ -0,0 +1,272 @@
>+// SPDX-License-Identifier: GPL-2.0+
>+/*
>+ * Copyright 2019-2020 NXP
>+ */
>+
>+#include <net/dsa.h>
>+
>+#define DSA_SANDBOX_MAGIC	0x00415344
>+#define DSA_SANDBOX_TAG_LEN	sizeof(struct dsa_sandbox_tag)
>+/*
>+ * This global flag is used to enable DSA just for DSA test so it
>+doesn't affect
>+ * the existing eth unit test.
>+ */
>+int dsa_sandbox_port_mask;
>+
>+struct dsa_sandbox_priv {
>+	int enabled;
>+	int port_enabled;
>+};
>+
>+struct dsa_sandbox_tag {
>+	u32 magic;
>+	u32 port;
>+};
>+
>+static int dsa_sandbox_port_enable(struct udevice *dev, int port,
>+				   struct phy_device *phy)
>+{
>+	struct dsa_sandbox_priv *priv = dev->priv;
>+
>+	if (!priv->enabled)
>+		return -EFAULT;
>+
>+	priv->port_enabled |= BIT(port);
>+
>+	return 0;
>+}
>+
>+static void dsa_sandbox_port_disable(struct udevice *dev, int port,
>+				     struct phy_device *phy)
>+{
>+	struct dsa_sandbox_priv *priv = dev->priv;
>+
>+	if (!priv->enabled)
>+		return;
>+
>+	priv->port_enabled &= ~BIT(port);
>+}
>+
>+static int dsa_sandbox_xmit(struct udevice *dev, int port, void *packet,
>+			    int length)
>+{
>+	struct dsa_sandbox_priv *priv = dev->priv;
>+	struct dsa_sandbox_tag *tag = packet;
>+
>+	if (!priv->enabled)
>+		return -EFAULT;
>+
>+	if (!(priv->port_enabled & BIT(port)))
>+		return -EFAULT;
>+
>+	tag->magic = DSA_SANDBOX_MAGIC;
>+	tag->port = port;
>+
>+	return 0;
>+}
>+
>+static int dsa_sandbox_rcv(struct udevice *dev, int *port, void *packet,
>+			   int length)
>+{
>+	struct dsa_sandbox_priv *priv = dev->priv;
>+	struct dsa_sandbox_tag *tag = packet;
>+
>+	if (!priv->enabled)
>+		return -EFAULT;
>+
>+	if (tag->magic != DSA_SANDBOX_MAGIC)
>+		return -EFAULT;
>+
>+	*port = tag->port;
>+	if (!(priv->port_enabled & BIT(*port)))
>+		return -EFAULT;
>+
>+	return 0;
>+}
>+
>+static const struct dsa_ops dsa_sandbox_ops = {
>+	.port_enable = dsa_sandbox_port_enable,
>+	.port_disable = dsa_sandbox_port_disable,
>+	.xmit = dsa_sandbox_xmit,
>+	.rcv = dsa_sandbox_rcv,
>+};
>+
>+static int dsa_sandbox_bind(struct udevice *dev) {
>+	struct dsa_perdev_platdata *pdata = dev->platdata;
>+
>+	/* must be at least 4 to match sandbox test DT */
>+	pdata->num_ports = 4;
>+	pdata->headroom = DSA_SANDBOX_TAG_LEN;
>+
>+	return 0;
>+}
>+
>+static int dsa_sandbox_probe(struct udevice *dev) {
>+	struct dsa_sandbox_priv *priv = dev_get_priv(dev);
>+
>+	/*
>+	 * return error if DSA is not being tested so we don't break existing
>+	 * eth test.
>+	 */
>+	if (!dsa_sandbox_port_mask)
>+		return -EINVAL;
>+
>+	priv->enabled = 1;
>+
>+	return 0;
>+}
>+
>+static int dsa_sandbox_remove(struct udevice *dev) {
>+	struct dsa_sandbox_priv *priv = dev_get_priv(dev);
>+
>+	priv->enabled = 0;
>+
>+	return 0;
>+}
>+
>+static const struct udevice_id dsa_sandbox_ids[] = {
>+	{ .compatible = "sandbox,dsa" },
>+	{ }
>+};
>+
>+U_BOOT_DRIVER(dsa_sandbox) = {
>+	.name		= "dsa_sandbox",
>+	.id		= UCLASS_DSA,
>+	.of_match	= dsa_sandbox_ids,
>+	.bind		= dsa_sandbox_bind,
>+	.probe		= dsa_sandbox_probe,
>+	.remove		= dsa_sandbox_remove,
>+	.ops		= &dsa_sandbox_ops,
>+	.priv_auto_alloc_size = sizeof(struct dsa_sandbox_priv),
>+	.platdata_auto_alloc_size = sizeof(struct dsa_perdev_platdata), };
>+
>+struct dsa_sandbox_eth_priv {
>+	int enabled;
>+	int started;
>+	int packet_length;
>+	uchar packet[PKTSIZE_ALIGN];
>+};
>+
>+static int dsa_eth_sandbox_start(struct udevice *dev) {
>+	struct dsa_sandbox_eth_priv *priv = dev->priv;
>+
>+	if (!priv->enabled)
>+		return -EFAULT;
>+
>+	priv->started = 1;
>+
>+	return 0;
>+}
>+
>+static void dsa_eth_sandbox_stop(struct udevice *dev) {
>+	struct dsa_sandbox_eth_priv *priv = dev->priv;
>+
>+	if (!priv->enabled)
>+		return;
>+
>+	priv->started = 0;
>+}
>+
>+static int dsa_eth_sandbox_send(struct udevice *dev, void *packet, int
>+length) {
>+	struct dsa_sandbox_eth_priv *priv = dev->priv;
>+	struct dsa_sandbox_tag *tag = packet;
>+
>+	if (!priv->enabled || !priv->started)
>+		return -EFAULT;
>+
>+	memcpy(priv->packet, packet, length);
>+	priv->packet_length = length;
>+
>+	/*
>+	 * for DSA test frames we only respond if the associated port is
>enabled
>+	 * in the dsa test port mask
>+	 */
>+
>+	if (tag->magic == DSA_SANDBOX_MAGIC) {
>+		int port = tag->port;
>+
>+		if (!(dsa_sandbox_port_mask & BIT(port)))
>+			/* drop the frame, port is not enabled */
>+			priv->packet_length = 0;
>+	}
>+
>+	return 0;
>+}
>+
>+static int dsa_eth_sandbox_recv(struct udevice *dev, int flags, uchar
>+**packetp) {
>+	struct dsa_sandbox_eth_priv *priv = dev->priv;
>+	int length = priv->packet_length;
>+
>+	if (!priv->enabled || !priv->started)
>+		return -EFAULT;
>+
>+	if (!length) {
>+		/* no frames pending, force a time-out */
>+		timer_test_add_offset(100);
>+		return -EAGAIN;
>+	}
>+
>+	*packetp = priv->packet;
>+	priv->packet_length = 0;
>+
>+	return length;
>+}
>+
>+static const struct eth_ops dsa_eth_sandbox_ops = {
>+	.start	= dsa_eth_sandbox_start,
>+	.send	= dsa_eth_sandbox_send,
>+	.recv	= dsa_eth_sandbox_recv,
>+	.stop	= dsa_eth_sandbox_stop,
>+};
>+
>+static int dsa_eth_sandbox_bind(struct udevice *dev) {
>+	return 0;
>+}
>+
>+static int dsa_eth_sandbox_probe(struct udevice *dev) {
>+	struct dsa_sandbox_eth_priv *priv = dev->priv;
>+
>+	priv->enabled = 1;
>+
>+	/*
>+	 * return error if DSA is not being tested do we don't break existing
>+	 * eth test.
>+	 */
>+	return dsa_sandbox_port_mask ? 0 : -EINVAL; }
>+
>+static int dsa_eth_sandbox_remove(struct udevice *dev) {
>+	struct dsa_sandbox_eth_priv *priv = dev->priv;
>+
>+	priv->enabled = 0;
>+
>+	return 0;
>+}
>+
>+static const struct udevice_id dsa_eth_sandbox_ids[] = {
>+	{ .compatible = "sandbox,dsa-eth" },
>+	{ }
>+};
>+
>+U_BOOT_DRIVER(dsa_eth_sandbox) = {
>+	.name		= "dsa_eth_sandbox",
>+	.id		= UCLASS_ETH,
>+	.of_match	= dsa_eth_sandbox_ids,
>+	.bind		= dsa_eth_sandbox_bind,
>+	.probe		= dsa_eth_sandbox_probe,
>+	.remove		= dsa_eth_sandbox_remove,
>+	.ops		= &dsa_eth_sandbox_ops,
>+	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
>+	.priv_auto_alloc_size = sizeof(struct dsa_sandbox_eth_priv), };
>--
>2.17.1

Kindly fix build error for target 
BUILDMAN="sandbox x86" TOOLCHAIN="i386"

https://travis-ci.org/github/p-priyanka-jain/u-boot/jobs/711090082


Regards
Priyanka


More information about the U-Boot mailing list