blob: 0f31a908c9d139ac707399c2f60f49f229ea9e26 [file] [log] [blame]
Claudiu Manoilc0566c22021-01-25 14:23:53 +02001/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright 2019-2021 NXP Semiconductors
4 */
5
6#ifndef __DSA_H__
7#define __DSA_H__
8
9#include <phy.h>
10#include <net.h>
11
12/**
13 * DSA stands for Distributed Switch Architecture and it is infrastructure
14 * intended to support drivers for Switches that rely on an intermediary
15 * Ethernet device for I/O. These switches may support cascading allowing
16 * them to be arranged as a tree.
17 * DSA is documented in detail in the Linux kernel documentation under
18 * Documentation/networking/dsa/dsa.txt
19 * The network layout of such a switch is shown below:
20 *
21 * |------|
22 * | eth0 | <--- master eth device (regular eth driver)
23 * |------|
24 * ^ |
25 * tag added by switch -->| |
26 * | |
27 * | |<-- tag added by DSA driver
28 * | v
29 * |--------------------------------------|
30 * | | CPU port | | <-- DSA (switch) device
31 * | ------------ | (DSA driver)
32 * | _________ _________ _________ |
33 * | | port0 | | port1 | ... | portn | | <-- ports as eth devices
34 * |-+-------+--+-------+-------+-------+-| ('dsa-port' eth driver)
35 *
36 * In U-Boot the intent is to allow access to front panel ports (shown at the
37 * bottom of the picture) through the master Ethernet dev (eth0 in the picture).
38 * Front panel ports are presented as regular Ethernet devices in U-Boot and
39 * they are expected to support the typical networking commands.
40 * In general DSA switches require the use of tags, extra headers added both by
41 * software on Tx and by the switch on Rx. These tags carry at a minimum port
42 * information and switch information for cascaded set-ups.
43 * In U-Boot these tags are inserted and parsed by the DSA switch driver, the
44 * class code helps with headroom/tailroom for the extra headers.
45 *
46 * TODO:
47 * - handle switch cascading, for now U-Boot only supports stand-alone switches.
48 * - Add support to probe DSA switches connected to a MDIO bus, this is needed
49 * to convert switch drivers that are now under drivers/net/phy.
50 */
51
52#define DSA_PORT_NAME_LENGTH 16
53
54/* Maximum number of ports each DSA device can have */
55#define DSA_MAX_PORTS 12
56
57/**
58 * struct dsa_ops - DSA operations
59 *
60 * @port_enable: Initialize a switch port for I/O.
61 * @port_disable: Disable I/O for a port.
62 * @xmit: Insert the DSA tag for transmission.
63 * DSA drivers receive a copy of the packet with headroom and
64 * tailroom reserved and set to 0. 'packet' points to headroom
65 * and 'length' is updated to include both head and tailroom.
66 * @rcv: Process the DSA tag on reception and return the port index
67 * from the h/w provided tag. Return the index via 'portp'.
68 * 'packet' and 'length' describe the frame as received from
69 * master including any additional headers.
70 */
71struct dsa_ops {
72 int (*port_enable)(struct udevice *dev, int port,
73 struct phy_device *phy);
74 void (*port_disable)(struct udevice *dev, int port,
75 struct phy_device *phy);
76 int (*xmit)(struct udevice *dev, int port, void *packet, int length);
77 int (*rcv)(struct udevice *dev, int *portp, void *packet, int length);
78};
79
80#define dsa_get_ops(dev) ((struct dsa_ops *)(dev)->driver->ops)
81
82/**
83 * struct dsa_port_pdata - DSA port platform data
84 *
85 * @phy: PHY device associated with this port.
86 * The uclass code attempts to set this field for all ports except CPU
87 * port, based on DT information. It may be NULL.
88 * @index: Port index in the DSA switch, set by the uclass code.
89 * @name: Name of the port Eth device. If a label property is present in the
90 * port DT node, it is used as name.
91 */
92struct dsa_port_pdata {
93 struct phy_device *phy;
94 u32 index;
95 char name[DSA_PORT_NAME_LENGTH];
96};
97
98/**
99 * struct dsa_pdata - Per-device platform data for DSA DM
100 *
101 * @num_ports: Number of ports the device has, must be <= DSA_MAX_PORTS.
102 * This number is extracted from the DT 'ports' node of this
103 * DSA device, and it counts the CPU port and all the other
104 * port subnodes including the disabled ones.
105 * @cpu_port: Index of the switch port linked to the master Ethernet.
106 * The uclass code sets this based on DT information.
107 * @master_node: OF node of the host Ethernet controller.
108 * @cpu_port_node: DT node of the switch's CPU port.
109 */
110struct dsa_pdata {
111 int num_ports;
112 u32 cpu_port;
113 ofnode master_node;
114 ofnode cpu_port_node;
115};
116
117/**
118 * dsa_set_tagging() - Configure the headroom and/or tailroom sizes
119 *
120 * The DSA class code allocates headroom and tailroom on Tx before
121 * calling the DSA driver's xmit function.
122 * All drivers must call this at probe time.
123 *
124 * @dev: DSA device pointer
125 * @headroom: Size, in bytes, of headroom needed for the DSA tag.
126 * @tailroom: Size, in bytes, of tailroom needed for the DSA tag.
127 * Total headroom and tailroom size should not exceed
128 * DSA_MAX_OVR.
129 * @return 0 if OK, -ve on error
130 */
131int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom);
132
133/* DSA helpers */
134
135/**
136 * dsa_get_master() - Return a reference to the master Ethernet device
137 *
138 * Can be called at driver probe time or later.
139 *
140 * @dev: DSA device pointer
141 * @return Master Eth 'udevice' pointer if OK, NULL on error
142 */
143struct udevice *dsa_get_master(struct udevice *dev);
144
145/**
146 * dsa_port_get_pdata() - Helper that returns the platdata of an active
147 * (non-CPU) DSA port device.
148 *
149 * Can be called at driver probe time or later.
150 *
151 * @pdev: DSA port device pointer
152 * @return 'dsa_port_pdata' pointer if OK, NULL on error
153 */
154static inline struct dsa_port_pdata *
155 dsa_port_get_pdata(struct udevice *pdev)
156{
157 struct eth_pdata *eth = dev_get_plat(pdev);
158
159 if (!eth)
160 return NULL;
161
162 return eth->priv_pdata;
163}
164
165#endif /* __DSA_H__ */