
-----Original Message----- From: U-Boot u-boot-bounces@lists.denx.de On Behalf Of Claudiu Manoil Sent: Tuesday, May 5, 2020 11:13 PM To: u-boot@lists.denx.de Cc: joe.hershberger@ni.com; Alexandru Marginean alexandru.marginean@nxp.com; Vladimir Oltean vladimir.oltean@nxp.com Subject: [PATCH v4 2/6] drivers: net: add a DSA sandbox driver
From: Alex Marginean alexandru.marginean@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@nxp.com Signed-off-by: Claudiu Manoil claudiu.manoil@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