1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2019-2021 NXP
10 #define DSA_SANDBOX_MAGIC 0x00415344
11 #define DSA_SANDBOX_TAG_LEN sizeof(struct dsa_sandbox_tag)
13 struct dsa_sandbox_priv {
14 struct eth_sandbox_priv *master_priv;
18 struct dsa_sandbox_tag {
23 static bool sb_dsa_port_enabled(struct udevice *dev, int port)
25 struct dsa_sandbox_priv *priv = dev_get_priv(dev);
27 return priv->port_en_mask & BIT(port);
30 static bool sb_dsa_master_enabled(struct udevice *dev)
32 struct dsa_sandbox_priv *priv = dev_get_priv(dev);
34 return !priv->master_priv->disabled;
37 static int dsa_sandbox_port_enable(struct udevice *dev, int port,
38 struct phy_device *phy)
40 struct dsa_sandbox_priv *priv = dev_get_priv(dev);
42 if (!sb_dsa_master_enabled(dev))
45 priv->port_en_mask |= BIT(port);
50 static void dsa_sandbox_port_disable(struct udevice *dev, int port,
51 struct phy_device *phy)
53 struct dsa_sandbox_priv *priv = dev_get_priv(dev);
55 priv->port_en_mask &= ~BIT(port);
58 static int dsa_sandbox_xmit(struct udevice *dev, int port, void *packet,
61 struct dsa_sandbox_tag *tag = packet;
63 if (!sb_dsa_master_enabled(dev))
66 if (!sb_dsa_port_enabled(dev, port))
69 tag->magic = DSA_SANDBOX_MAGIC;
75 static int dsa_sandbox_rcv(struct udevice *dev, int *port, void *packet,
78 struct dsa_sandbox_tag *tag = packet;
80 if (!sb_dsa_master_enabled(dev))
83 if (tag->magic != DSA_SANDBOX_MAGIC)
87 if (!sb_dsa_port_enabled(dev, tag->port))
93 static const struct dsa_ops dsa_sandbox_ops = {
94 .port_enable = dsa_sandbox_port_enable,
95 .port_disable = dsa_sandbox_port_disable,
96 .xmit = dsa_sandbox_xmit,
97 .rcv = dsa_sandbox_rcv,
100 static int sb_dsa_handler(struct udevice *dev, void *packet,
103 struct eth_sandbox_priv *master_priv;
104 struct dsa_sandbox_tag *tag = packet;
105 struct udevice *dsa_dev;
110 /* this emulates the switch hw and the network side */
111 if (tag->magic != DSA_SANDBOX_MAGIC)
114 port_index = tag->port;
115 master_priv = dev_get_priv(dev);
116 dsa_dev = master_priv->priv;
117 if (!sb_dsa_port_enabled(dsa_dev, port_index))
120 packet += DSA_SANDBOX_TAG_LEN;
121 len -= DSA_SANDBOX_TAG_LEN;
123 if (!sandbox_eth_arp_req_to_reply(dev, packet, len))
125 if (!sandbox_eth_ping_req_to_reply(dev, packet, len))
131 master_priv->recv_packets--;
132 i = master_priv->recv_packets;
133 rx_buf = master_priv->recv_packet_buffer[i];
134 len = master_priv->recv_packet_length[i];
135 memmove(rx_buf + DSA_SANDBOX_TAG_LEN, rx_buf, len);
138 tag->magic = DSA_SANDBOX_MAGIC;
139 tag->port = port_index;
140 len += DSA_SANDBOX_TAG_LEN;
141 master_priv->recv_packet_length[i] = len;
142 master_priv->recv_packets++;
147 static int dsa_sandbox_probe(struct udevice *dev)
149 struct dsa_sandbox_priv *priv = dev_get_priv(dev);
150 struct udevice *master = dsa_get_master(dev);
151 struct eth_sandbox_priv *master_priv;
156 dsa_set_tagging(dev, DSA_SANDBOX_TAG_LEN, 0);
158 master_priv = dev_get_priv(master);
159 master_priv->priv = dev;
160 master_priv->tx_handler = sb_dsa_handler;
162 priv->master_priv = master_priv;
167 static const struct udevice_id dsa_sandbox_ids[] = {
168 { .compatible = "sandbox,dsa" },
172 U_BOOT_DRIVER(dsa_sandbox) = {
173 .name = "dsa_sandbox",
175 .of_match = dsa_sandbox_ids,
176 .probe = dsa_sandbox_probe,
177 .ops = &dsa_sandbox_ops,
178 .priv_auto = sizeof(struct dsa_sandbox_priv),