[U-Boot] [PATCH v2 1/6] net: introduce DSA class for Ethernet switches

Joe Hershberger joe.hershberger at ni.com
Sat Nov 30 00:56:41 UTC 2019


Hi Alex,

On Mon, Nov 25, 2019 at 9:54 AM Alex Marginean
<alexandru.marginean at nxp.com> wrote:
>
> DSA stands for Distributed Switch Architecture and it covers switches that
> are connected to the CPU through an Ethernet link and generally use frame
> tags to pass information about the source/destination ports to/from CPU.
> Front panel ports are presented as regular ethernet devices in U-Boot and
> they are expected to support the typical networking commands.
> DSA switches may be cascaded, DSA class code does not currently support
> this.

Is it expected to eventually retrofit the other switch drivers that we
have in U-Boot to use this?

>
> Signed-off-by: Alex Marginean <alexandru.marginean at nxp.com>
> ---
>  drivers/net/Kconfig    |  13 ++
>  include/dm/uclass-id.h |   1 +
>  include/dsa.h          | 140 ++++++++++++++++

Please use include/net/dsa.h

>  net/Makefile           |   1 +
>  net/dsa-uclass.c       | 369 +++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 524 insertions(+)
>  create mode 100644 include/dsa.h
>  create mode 100644 net/dsa-uclass.c
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 4182897d89..a4157cb122 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -37,6 +37,19 @@ config DM_MDIO_MUX
>           This is currently implemented in net/mdio-mux-uclass.c
>           Look in include/miiphy.h for details.
>
> +config DM_DSA
> +       bool "Enable Driver Model for DSA switches"
> +       depends on DM_ETH && DM_MDIO
> +       help
> +         Enable Driver Model for DSA switches
> +
> +         Adds UCLASS_DSA class supporting switches that follow the Distributed
> +         Switch Architecture (DSA).  These switches rely on the presence of a
> +         management switch port connected to an Ethernet controller capable of
> +         receiving frames from the switch.  This host Ethernet controller is
> +         called "master" and "cpu" in DSA terminology.
> +         This is currently implemented in net/dsa-uclass.c
> +
>  config MDIO_SANDBOX
>         depends on DM_MDIO && SANDBOX
>         default y
> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
> index 0c563d898b..8f37a91488 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -42,6 +42,7 @@ enum uclass_id {
>         UCLASS_DISPLAY,         /* Display (e.g. DisplayPort, HDMI) */
>         UCLASS_DSI_HOST,        /* Display Serial Interface host */
>         UCLASS_DMA,             /* Direct Memory Access */
> +       UCLASS_DSA,             /* Distributed (Ethernet) Switch Architecture */
>         UCLASS_EFI,             /* EFI managed devices */
>         UCLASS_ETH,             /* Ethernet device */
>         UCLASS_FIRMWARE,        /* Firmware */
> diff --git a/include/dsa.h b/include/dsa.h
> new file mode 100644
> index 0000000000..707a1d7e6f
> --- /dev/null
> +++ b/include/dsa.h
> @@ -0,0 +1,140 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 NXP
> + */
> +
> +#ifndef __DSA_H__
> +#define __DSA_H__
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <phy.h>
> +
> +/**
> + * DSA stands for Distributed Switch Architecture and it is infrastructure
> + * intended to support drivers for Switches that rely on an intermediary
> + * Ethernet device for I/O.  These switches may support cascading allowing
> + * them to be arranged as a tree.
> + * DSA is documented in detail in the Linux kernel documentation under
> + * Documentation/networking/dsa/dsa.txt
> + * The network layout of such a switch is shown below:
> + *
> + *         |---------------------------
> + *         | CPU network device (eth0)|
> + *         ----------------------------
> + *         | <tag added by switch     |
> + *         |                          |
> + *         |                          |
> + *         |        tag added by CPU> |
> + *     |--------------------------------------------|
> + *     | Switch driver                              |
> + *     |--------------------------------------------|
> + *         ||        ||         ||
> + *     |-------|  |-------|  |-------|
> + *     | sw0p0 |  | sw0p1 |  | sw0p2 |
> + *     |-------|  |-------|  |-------|
> + *
> + * In U-Boot the intent is to allow acces to front panel ports (shown at the

acces  ->  access

> + * bottom of the picture) though the master Ethernet port (eth0 in the picture).
> + * Front panel ports are presented as regular ethernet devices in U-Boot and

ethernet  -> Ethernet

> + * they are expected to support the typical networking commands.
> + * In general DSA switches require the use of tags, extra headers added both by
> + * software on Tx and by the switch on Rx.  These tags carry at a minimum port
> + * information and switch information for cascaded set-ups.
> + * In U-Boot these tags are inserted and parsed by the DSA switch driver, the
> + * class code helps with headroom/tailroom for the extra headers.
> + *
> + * TODO:
> + * - handle switch cascading, for now U-Boot only supports stand-alone switches.
> + * - put master Eth in promisc mode, this isn't needed right now but will be
> + *   sooner or later.
> + *

Drop empty line

> + */
> +
> +#define DSA_PORT_NAME_LENGTH   16
> +
> +/* Maximum number of ports each DSA device can have */
> +#define DSA_MAX_PORTS          12
> +/* Used to size internal buffers, no support for jumbo yet */
> +#define DSA_MAX_FRAME_SIZE     2048
> +
> +/**
> + * struct dsa_ops - DSA operations
> + *
> + * @port_enable:  Initialize a switch port for I/O
> + * @port_disable: Disable a port
> + * @xmit:         Insert the DSA tag for transmission
> + *                DSA drivers receive a copy of the packet with headroom and
> + *                tailroom reserved and set to 0.
> + *                Packet points to headroom and length is updated to include
> + *                both headroom and tailroom
> + * @rcv:          Process the DSA tag on reception
> + *                Packet and length describe the frame as received from master
> + *                including any additional headers
> + */
> +struct dsa_ops {
> +       int (*port_enable)(struct udevice *dev, int port,
> +                          struct phy_device *phy);
> +       void (*port_disable)(struct udevice *dev, int port,
> +                            struct phy_device *phy);
> +       int (*xmit)(struct udevice *dev, int port, void *packet, int length);
> +       int (*rcv)(struct udevice *dev, int *port, void *packet, int length);
> +};
> +
> +#define dsa_get_ops(dev) ((struct dsa_ops *)(dev)->driver->ops)
> +
> +/**
> + * struct dsa_port_platdata - DSA port platform data
> + *
> + * @dev :  Port u-device
> + *         Uclass code sets this field for all ports
> + * @phy:   PHY device associated with this port
> + *         Uclass code sets this field for all ports except CPU port, based on
> + *         DT information.  It may be NULL.
> + * @node:  Port DT node, if any.  Uclass code sets this field.
> + * @index: Port index in the DSA switch, set by class code.
> + * @name:  Name of the port Eth device.  If a label property is present in the
> + *         port DT node, it is used as name.  Drivers can use custom names by
> + *         populating this field, otherwise class code generates a default.
> + */
> +struct dsa_port_platdata {
> +       struct udevice *dev;
> +       struct phy_device *phy;
> +       ofnode node;
> +       int index;
> +       char name[DSA_PORT_NAME_LENGTH];
> +};
> +
> +/**
> + * struct dsa_perdev_platdata - Per-device platform data for DSA DM
> + *
> + * @num_ports:   Number of ports the device has, must be <= DSA_MAX_PORTS
> + *               All DSA drivers must set this at _bind
> + * @headroom:    Size, in bytes, of headroom needed for the DSA tag
> + *               All DSA drivers must set this at _bind or _probe
> + * @tailroom:    Size, in bytes, of tailroom needed for the DSA tag
> + *               DSA class code allocates headroom and tailroom on Tx before
> + *               calling DSA driver xmit function
> + *               All DSA drivers must set this at _bind or _probe
> + * @master_node: DT node of the master Ethernet.  DT is optional so this may be
> + *               null.
> + * @master_dev:  Ethernet device to be used as master.  Uclass code sets this
> + *               based on DT information if present, otherwise drivers must set
> + *               this field in _probe.
> + * @cpu_port:    Index of switch port linked to master Ethernet.
> + *               Uclass code sets this based on DT information if present,
> + *               otherwise drivers must set this field in _bind.
> + * @port:        per-port data
> + */
> +struct dsa_perdev_platdata {
> +       int num_ports;
> +       int headroom;
> +       int tailroom;
> +
> +       ofnode master_node;
> +       struct udevice *master_dev;
> +       int cpu_port;
> +       struct dsa_port_platdata port[DSA_MAX_PORTS];
> +};
> +
> +#endif /* __DSA_H__ */

[...]


More information about the U-Boot mailing list