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