net: Introduce DSA class for Ethernet switches
[platform/kernel/u-boot.git] / net / dsa-uclass.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019-2021 NXP
4  */
5
6 #include <net/dsa.h>
7 #include <dm/lists.h>
8 #include <dm/device_compat.h>
9 #include <dm/device-internal.h>
10 #include <dm/uclass-internal.h>
11 #include <linux/bitmap.h>
12 #include <miiphy.h>
13
14 #define DSA_PORT_CHILD_DRV_NAME "dsa-port"
15
16 /* per-device internal state structure */
17 struct dsa_priv {
18         struct phy_device *cpu_port_fixed_phy;
19         struct udevice *master_dev;
20         int num_ports;
21         u32 cpu_port;
22         int headroom;
23         int tailroom;
24 };
25
26 /* external API */
27 int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom)
28 {
29         struct dsa_priv *priv;
30
31         if (!dev || !dev_get_uclass_priv(dev))
32                 return -ENODEV;
33
34         if (headroom + tailroom > DSA_MAX_OVR)
35                 return -EINVAL;
36
37         priv = dev_get_uclass_priv(dev);
38
39         if (headroom > 0)
40                 priv->headroom = headroom;
41         if (tailroom > 0)
42                 priv->tailroom = tailroom;
43
44         return 0;
45 }
46
47 /* returns the DSA master Ethernet device */
48 struct udevice *dsa_get_master(struct udevice *dev)
49 {
50         struct dsa_priv *priv = dev_get_uclass_priv(dev);
51
52         if (!priv)
53                 return NULL;
54
55         return priv->master_dev;
56 }
57
58 /*
59  * Start the desired port, the CPU port and the master Eth interface.
60  * TODO: if cascaded we may need to _start ports in other switches too
61  */
62 static int dsa_port_start(struct udevice *pdev)
63 {
64         struct udevice *dev = dev_get_parent(pdev);
65         struct dsa_priv *priv = dev_get_uclass_priv(dev);
66         struct udevice *master = dsa_get_master(dev);
67         struct dsa_ops *ops = dsa_get_ops(dev);
68         int err;
69
70         if (!priv)
71                 return -ENODEV;
72
73         if (!master) {
74                 dev_err(pdev, "DSA master Ethernet device not found!\n");
75                 return -EINVAL;
76         }
77
78         if (ops->port_enable) {
79                 struct dsa_port_pdata *port_pdata;
80
81                 port_pdata = dev_get_parent_plat(pdev);
82                 err = ops->port_enable(dev, port_pdata->index,
83                                        port_pdata->phy);
84                 if (err)
85                         return err;
86
87                 err = ops->port_enable(dev, priv->cpu_port,
88                                        priv->cpu_port_fixed_phy);
89                 if (err)
90                         return err;
91         }
92
93         return eth_get_ops(master)->start(master);
94 }
95
96 /* Stop the desired port, the CPU port and the master Eth interface */
97 static void dsa_port_stop(struct udevice *pdev)
98 {
99         struct udevice *dev = dev_get_parent(pdev);
100         struct dsa_priv *priv = dev_get_uclass_priv(dev);
101         struct udevice *master = dsa_get_master(dev);
102         struct dsa_ops *ops = dsa_get_ops(dev);
103
104         if (!priv)
105                 return;
106
107         if (ops->port_disable) {
108                 struct dsa_port_pdata *port_pdata;
109
110                 port_pdata = dev_get_parent_plat(pdev);
111                 ops->port_disable(dev, port_pdata->index, port_pdata->phy);
112                 ops->port_disable(dev, priv->cpu_port, NULL);
113         }
114
115         /*
116          * stop master only if it's active, don't probe it otherwise.
117          * Under normal usage it would be active because we're using it, but
118          * during tear-down it may have been removed ahead of us.
119          */
120         if (master && device_active(master))
121                 eth_get_ops(master)->stop(master);
122 }
123
124 /*
125  * Insert a DSA tag and call master Ethernet send on the resulting packet
126  * We copy the frame to a stack buffer where we have reserved headroom and
127  * tailroom space.  Headroom and tailroom are set to 0.
128  */
129 static int dsa_port_send(struct udevice *pdev, void *packet, int length)
130 {
131         struct udevice *dev = dev_get_parent(pdev);
132         struct dsa_priv *priv = dev_get_uclass_priv(dev);
133         int head = priv->headroom, tail = priv->tailroom;
134         struct udevice *master = dsa_get_master(dev);
135         struct dsa_ops *ops = dsa_get_ops(dev);
136         uchar dsa_packet_tmp[PKTSIZE_ALIGN];
137         struct dsa_port_pdata *port_pdata;
138         int err;
139
140         if (!master)
141                 return -EINVAL;
142
143         if (length + head + tail > PKTSIZE_ALIGN)
144                 return -EINVAL;
145
146         memset(dsa_packet_tmp, 0, head);
147         memset(dsa_packet_tmp + head + length, 0, tail);
148         memcpy(dsa_packet_tmp + head, packet, length);
149         length += head + tail;
150         /* copy back to preserve original buffer alignment */
151         memcpy(packet, dsa_packet_tmp, length);
152
153         port_pdata = dev_get_parent_plat(pdev);
154         err = ops->xmit(dev, port_pdata->index, packet, length);
155         if (err)
156                 return err;
157
158         return eth_get_ops(master)->send(master, packet, length);
159 }
160
161 /* Receive a frame from master Ethernet, process it and pass it on */
162 static int dsa_port_recv(struct udevice *pdev, int flags, uchar **packetp)
163 {
164         struct udevice *dev = dev_get_parent(pdev);
165         struct dsa_priv *priv = dev_get_uclass_priv(dev);
166         int head = priv->headroom, tail = priv->tailroom;
167         struct udevice *master = dsa_get_master(dev);
168         struct dsa_ops *ops = dsa_get_ops(dev);
169         struct dsa_port_pdata *port_pdata;
170         int length, port_index, err;
171
172         if (!master)
173                 return -EINVAL;
174
175         length = eth_get_ops(master)->recv(master, flags, packetp);
176         if (length <= 0)
177                 return length;
178
179         /*
180          * If we receive frames from a different port or frames that DSA driver
181          * doesn't like we discard them here.
182          * In case of discard we return with no frame and expect to be called
183          * again instead of looping here, so upper layer can deal with timeouts.
184          */
185         port_pdata = dev_get_parent_plat(pdev);
186         err = ops->rcv(dev, &port_index, *packetp, length);
187         if (err || port_index != port_pdata->index || (length <= head + tail)) {
188                 if (eth_get_ops(master)->free_pkt)
189                         eth_get_ops(master)->free_pkt(master, *packetp, length);
190                 return -EAGAIN;
191         }
192
193         /*
194          * We move the pointer over headroom here to avoid a copy.  If free_pkt
195          * gets called we move the pointer back before calling master free_pkt.
196          */
197         *packetp += head;
198
199         return length - head - tail;
200 }
201
202 static int dsa_port_free_pkt(struct udevice *pdev, uchar *packet, int length)
203 {
204         struct udevice *dev = dev_get_parent(pdev);
205         struct udevice *master = dsa_get_master(dev);
206         struct dsa_priv *priv;
207
208         if (!master)
209                 return -EINVAL;
210
211         priv = dev_get_uclass_priv(dev);
212         if (eth_get_ops(master)->free_pkt) {
213                 /* return the original pointer and length to master Eth */
214                 packet -= priv->headroom;
215                 length += priv->headroom - priv->tailroom;
216
217                 return eth_get_ops(master)->free_pkt(master, packet, length);
218         }
219
220         return 0;
221 }
222
223 static int dsa_port_of_to_pdata(struct udevice *pdev)
224 {
225         struct dsa_port_pdata *port_pdata;
226         struct dsa_pdata *dsa_pdata;
227         struct eth_pdata *eth_pdata;
228         struct udevice *dev;
229         const char *label;
230         u32 index;
231         int err;
232
233         if (!pdev)
234                 return -ENODEV;
235
236         err = ofnode_read_u32(dev_ofnode(pdev), "reg", &index);
237         if (err)
238                 return err;
239
240         dev = dev_get_parent(pdev);
241         dsa_pdata = dev_get_uclass_plat(dev);
242
243         port_pdata = dev_get_parent_plat(pdev);
244         port_pdata->index = index;
245
246         label = ofnode_read_string(dev_ofnode(pdev), "label");
247         if (label)
248                 strncpy(port_pdata->name, label, DSA_PORT_NAME_LENGTH);
249
250         eth_pdata = dev_get_plat(pdev);
251         eth_pdata->priv_pdata = port_pdata;
252
253         dev_dbg(pdev, "port %d node %s\n", port_pdata->index,
254                 ofnode_get_name(dev_ofnode(pdev)));
255
256         return 0;
257 }
258
259 static const struct eth_ops dsa_port_ops = {
260         .start          = dsa_port_start,
261         .send           = dsa_port_send,
262         .recv           = dsa_port_recv,
263         .stop           = dsa_port_stop,
264         .free_pkt       = dsa_port_free_pkt,
265 };
266
267 static int dsa_port_probe(struct udevice *pdev)
268 {
269         struct udevice *dev = dev_get_parent(pdev);
270         struct eth_pdata *eth_pdata, *master_pdata;
271         unsigned char env_enetaddr[ARP_HLEN];
272         struct dsa_port_pdata *port_pdata;
273         struct dsa_priv *dsa_priv;
274         struct udevice *master;
275
276         port_pdata = dev_get_parent_plat(pdev);
277         dsa_priv = dev_get_uclass_priv(dev);
278
279         port_pdata->phy = dm_eth_phy_connect(pdev);
280         if (!port_pdata->phy)
281                 return -ENODEV;
282
283         /*
284          * Inherit port's hwaddr from the DSA master, unless the port already
285          * has a unique MAC address specified in the environment.
286          */
287         eth_env_get_enetaddr_by_index("eth", dev_seq(pdev), env_enetaddr);
288         if (!is_zero_ethaddr(env_enetaddr))
289                 return 0;
290
291         master = dsa_get_master(dev);
292         if (!master)
293                 return 0;
294
295         master_pdata = dev_get_plat(master);
296         eth_pdata = dev_get_plat(pdev);
297         memcpy(eth_pdata->enetaddr, master_pdata->enetaddr, ARP_HLEN);
298         eth_env_set_enetaddr_by_index("eth", dev_seq(pdev),
299                                       master_pdata->enetaddr);
300
301         return 0;
302 }
303
304 static int dsa_port_remove(struct udevice *pdev)
305 {
306         struct udevice *dev = dev_get_parent(pdev);
307         struct dsa_port_pdata *port_pdata;
308         struct dsa_priv *dsa_priv;
309
310         port_pdata = dev_get_parent_plat(pdev);
311         dsa_priv = dev_get_uclass_priv(dev);
312
313         port_pdata->phy = NULL;
314
315         return 0;
316 }
317
318 U_BOOT_DRIVER(dsa_port) = {
319         .name   = DSA_PORT_CHILD_DRV_NAME,
320         .id     = UCLASS_ETH,
321         .ops    = &dsa_port_ops,
322         .probe  = dsa_port_probe,
323         .remove = dsa_port_remove,
324         .of_to_plat = dsa_port_of_to_pdata,
325         .plat_auto = sizeof(struct eth_pdata),
326 };
327
328 /*
329  * This function mostly deals with pulling information out of the device tree
330  * into the pdata structure.
331  * It goes through the list of switch ports, registers an eth device for each
332  * front panel port and identifies the cpu port connected to master eth device.
333  * TODO: support cascaded switches
334  */
335 static int dsa_post_bind(struct udevice *dev)
336 {
337         struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
338         ofnode node = dev_ofnode(dev), pnode;
339         int i, err, first_err = 0;
340
341         if (!pdata || !ofnode_valid(node))
342                 return -ENODEV;
343
344         pdata->master_node = ofnode_null();
345
346         node = ofnode_find_subnode(node, "ports");
347         if (!ofnode_valid(node))
348                 node = ofnode_find_subnode(node, "ethernet-ports");
349         if (!ofnode_valid(node)) {
350                 dev_err(dev, "ports node is missing under DSA device!\n");
351                 return -EINVAL;
352         }
353
354         pdata->num_ports = ofnode_get_child_count(node);
355         if (pdata->num_ports <= 0 || pdata->num_ports > DSA_MAX_PORTS) {
356                 dev_err(dev, "invalid number of ports (%d)\n",
357                         pdata->num_ports);
358                 return -EINVAL;
359         }
360
361         /* look for the CPU port */
362         ofnode_for_each_subnode(pnode, node) {
363                 u32 ethernet;
364
365                 if (ofnode_read_u32(pnode, "ethernet", &ethernet))
366                         continue;
367
368                 pdata->master_node = ofnode_get_by_phandle(ethernet);
369                 pdata->cpu_port_node = pnode;
370                 break;
371         }
372
373         if (!ofnode_valid(pdata->master_node)) {
374                 dev_err(dev, "master eth node missing!\n");
375                 return -EINVAL;
376         }
377
378         if (ofnode_read_u32(pnode, "reg", &pdata->cpu_port)) {
379                 dev_err(dev, "CPU port node not valid!\n");
380                 return -EINVAL;
381         }
382
383         dev_dbg(dev, "master node %s on port %d\n",
384                 ofnode_get_name(pdata->master_node), pdata->cpu_port);
385
386         for (i = 0; i < pdata->num_ports; i++) {
387                 char name[DSA_PORT_NAME_LENGTH];
388                 struct udevice *pdev;
389
390                 /*
391                  * If this is the CPU port don't register it as an ETH device,
392                  * we skip it on purpose since I/O to/from it from the CPU
393                  * isn't useful.
394                  */
395                 if (i == pdata->cpu_port)
396                         continue;
397
398                 /*
399                  * Set up default port names.  If present, DT port labels
400                  * will override the default port names.
401                  */
402                 snprintf(name, DSA_PORT_NAME_LENGTH, "%s@%d", dev->name, i);
403
404                 ofnode_for_each_subnode(pnode, node) {
405                         u32 reg;
406
407                         if (ofnode_read_u32(pnode, "reg", &reg))
408                                 continue;
409
410                         if (reg == i)
411                                 break;
412                 }
413
414                 /*
415                  * skip registration if port id not found or if the port
416                  * is explicitly disabled in DT
417                  */
418                 if (!ofnode_valid(pnode) || !ofnode_is_available(pnode))
419                         continue;
420
421                 err = device_bind_driver_to_node(dev, DSA_PORT_CHILD_DRV_NAME,
422                                                  name, pnode, &pdev);
423                 if (pdev) {
424                         struct dsa_port_pdata *port_pdata;
425
426                         port_pdata = dev_get_parent_plat(pdev);
427                         strncpy(port_pdata->name, name, DSA_PORT_NAME_LENGTH);
428                         pdev->name = port_pdata->name;
429                 }
430
431                 /* try to bind all ports but keep 1st error */
432                 if (err && !first_err)
433                         first_err = err;
434         }
435
436         if (first_err)
437                 return first_err;
438
439         dev_dbg(dev, "DSA ports successfully bound\n");
440
441         return 0;
442 }
443
444 /**
445  * Initialize the uclass per device internal state structure (priv).
446  * TODO: pick up references to other switch devices here, if we're cascaded.
447  */
448 static int dsa_pre_probe(struct udevice *dev)
449 {
450         struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
451         struct dsa_priv *priv = dev_get_uclass_priv(dev);
452
453         if (!pdata || !priv)
454                 return -ENODEV;
455
456         priv->num_ports = pdata->num_ports;
457         priv->cpu_port = pdata->cpu_port;
458         priv->cpu_port_fixed_phy = fixed_phy_create(pdata->cpu_port_node);
459         if (!priv->cpu_port_fixed_phy) {
460                 dev_err(dev, "Failed to register fixed-link for CPU port\n");
461                 return -ENODEV;
462         }
463
464         uclass_find_device_by_ofnode(UCLASS_ETH, pdata->master_node,
465                                      &priv->master_dev);
466         return 0;
467 }
468
469 UCLASS_DRIVER(dsa) = {
470         .id = UCLASS_DSA,
471         .name = "dsa",
472         .post_bind = dsa_post_bind,
473         .pre_probe = dsa_pre_probe,
474         .per_device_auto = sizeof(struct dsa_priv),
475         .per_device_plat_auto = sizeof(struct dsa_pdata),
476         .per_child_plat_auto = sizeof(struct dsa_port_pdata),
477         .flags = DM_UC_FLAG_SEQ_ALIAS,
478 };