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

Alexandru Marginean alexm.osslist at gmail.com
Sun Dec 1 02:21:49 UTC 2019


Hi Joe,

On 11/30/2019 1:56 AM, Joe Hershberger wrote:
> 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?

For now I would like to at least make sure that the uclass code allows 
that to happen.  Longer term yes, it would be nice to get existing 
drivers converted.  This is applicable to switches that rely on a master 
Eth device for I/O.  The list should include switches that use DSA in 
kernel, of course:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/dsa

Some of these are under PHYs in U-Boot right now (like b53, mv88exxx), 
hooked up to the master Eth.  This works, but comes with limitations, 
like this in b53 driver:
  * The configuration determines which PHY ports to activate using the
  * CONFIG_B53_PHY_PORTS bitmask. Set bit N will active port N and so on.
Having these drivers converted should come with some benefits:
- their DT nodes would be in sync with the kernel DSA bindings,
- users would have some run-time control over the switch ports used for I/O,
- driving PHYs of front panel ports comes more naturally with these 
ports being registered as eth devices.

There are other switches which don't fall under DSA, those that present 
some sort of direct I/O interface to the CPU and don't rely on a master 
Eth device.  These switched may not follow DSA bindings, since they are 
not technically DSA.  For them we could either have a more generic Eth 
switch class or just let the drivers register the switch device or the 
ports on the switch as Eth devices.

I'll send a v3 with fixes for the comments below.

Thanks!
Alex

>>
>> 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__ */
> 
> [...]
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
> 


More information about the U-Boot mailing list