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