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 */
dsa_set_tagging(struct udevice * dev,ushort headroom,ushort tailroom)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 */
dsa_get_master(struct udevice * dev)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  */
dsa_port_start(struct udevice * pdev)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 */
dsa_port_stop(struct udevice * pdev)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, priv->cpu_port_fixed_phy);
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  */
dsa_port_send(struct udevice * pdev,void * packet,int length)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 */
dsa_port_recv(struct udevice * pdev,int flags,uchar ** packetp)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 
dsa_port_free_pkt(struct udevice * pdev,uchar * packet,int length)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 
dsa_port_of_to_pdata(struct udevice * pdev)199 static int dsa_port_of_to_pdata(struct udevice *pdev)
200 {
201 	struct dsa_port_pdata *port_pdata;
202 	struct eth_pdata *eth_pdata;
203 	const char *label;
204 	u32 index;
205 	int err;
206 
207 	if (!pdev)
208 		return -ENODEV;
209 
210 	err = ofnode_read_u32(dev_ofnode(pdev), "reg", &index);
211 	if (err)
212 		return err;
213 
214 	port_pdata = dev_get_parent_plat(pdev);
215 	port_pdata->index = index;
216 
217 	label = ofnode_read_string(dev_ofnode(pdev), "label");
218 	if (label)
219 		strlcpy(port_pdata->name, label, DSA_PORT_NAME_LENGTH);
220 
221 	eth_pdata = dev_get_plat(pdev);
222 	eth_pdata->priv_pdata = port_pdata;
223 
224 	dev_dbg(pdev, "port %d node %s\n", port_pdata->index,
225 		ofnode_get_name(dev_ofnode(pdev)));
226 
227 	return 0;
228 }
229 
230 static const struct eth_ops dsa_port_ops = {
231 	.start		= dsa_port_start,
232 	.send		= dsa_port_send,
233 	.recv		= dsa_port_recv,
234 	.stop		= dsa_port_stop,
235 	.free_pkt	= dsa_port_free_pkt,
236 };
237 
238 /*
239  * Inherit port's hwaddr from the DSA master, unless the port already has a
240  * unique MAC address specified in the environment.
241  */
dsa_port_set_hwaddr(struct udevice * pdev,struct udevice * master)242 static void dsa_port_set_hwaddr(struct udevice *pdev, struct udevice *master)
243 {
244 	struct eth_pdata *eth_pdata, *master_pdata;
245 	unsigned char env_enetaddr[ARP_HLEN];
246 
247 	eth_env_get_enetaddr_by_index("eth", dev_seq(pdev), env_enetaddr);
248 	if (!is_zero_ethaddr(env_enetaddr)) {
249 		/* individual port mac addrs require master to be promisc */
250 		struct eth_ops *eth_ops = eth_get_ops(master);
251 
252 		if (eth_ops->set_promisc)
253 			eth_ops->set_promisc(master, 1);
254 
255 		return;
256 	}
257 
258 	master_pdata = dev_get_plat(master);
259 	eth_pdata = dev_get_plat(pdev);
260 	memcpy(eth_pdata->enetaddr, master_pdata->enetaddr, ARP_HLEN);
261 	eth_env_set_enetaddr_by_index("eth", dev_seq(pdev),
262 				      master_pdata->enetaddr);
263 }
264 
dsa_port_probe(struct udevice * pdev)265 static int dsa_port_probe(struct udevice *pdev)
266 {
267 	struct udevice *dev = dev_get_parent(pdev);
268 	struct dsa_ops *ops = dsa_get_ops(dev);
269 	struct dsa_port_pdata *port_pdata;
270 	struct udevice *master;
271 	int err;
272 
273 	port_pdata = dev_get_parent_plat(pdev);
274 
275 	port_pdata->phy = dm_eth_phy_connect(pdev);
276 	if (!port_pdata->phy)
277 		return -ENODEV;
278 
279 	master = dsa_get_master(dev);
280 	if (!master)
281 		return -ENODEV;
282 
283 	/*
284 	 * Probe the master device. We depend on the master device for proper
285 	 * operation and we also need it for MAC inheritance below.
286 	 *
287 	 * TODO: we assume the master device is always there and doesn't get
288 	 * removed during runtime.
289 	 */
290 	err = device_probe(master);
291 	if (err)
292 		return err;
293 
294 	dsa_port_set_hwaddr(pdev, master);
295 
296 	if (ops->port_probe) {
297 		err = ops->port_probe(dev, port_pdata->index,
298 				      port_pdata->phy);
299 		if (err)
300 			return err;
301 	}
302 
303 	return 0;
304 }
305 
dsa_port_remove(struct udevice * pdev)306 static int dsa_port_remove(struct udevice *pdev)
307 {
308 	struct dsa_port_pdata *port_pdata = dev_get_parent_plat(pdev);
309 
310 	port_pdata->phy = NULL;
311 
312 	return 0;
313 }
314 
315 U_BOOT_DRIVER(dsa_port) = {
316 	.name	= DSA_PORT_CHILD_DRV_NAME,
317 	.id	= UCLASS_ETH,
318 	.ops	= &dsa_port_ops,
319 	.probe	= dsa_port_probe,
320 	.remove	= dsa_port_remove,
321 	.of_to_plat = dsa_port_of_to_pdata,
322 	.plat_auto = sizeof(struct eth_pdata),
323 };
324 
325 /*
326  * This function mostly deals with pulling information out of the device tree
327  * into the pdata structure.
328  * It goes through the list of switch ports, registers an eth device for each
329  * front panel port and identifies the cpu port connected to master eth device.
330  * TODO: support cascaded switches
331  */
dsa_post_bind(struct udevice * dev)332 static int dsa_post_bind(struct udevice *dev)
333 {
334 	struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
335 	ofnode node = dev_ofnode(dev), pnode;
336 	int i, err, first_err = 0;
337 
338 	if (!ofnode_valid(node))
339 		return -ENODEV;
340 
341 	pdata->master_node = ofnode_null();
342 
343 	node = ofnode_find_subnode(node, "ports");
344 	if (!ofnode_valid(node))
345 		node = ofnode_find_subnode(node, "ethernet-ports");
346 	if (!ofnode_valid(node)) {
347 		dev_err(dev, "ports node is missing under DSA device!\n");
348 		return -EINVAL;
349 	}
350 
351 	pdata->num_ports = ofnode_get_child_count(node);
352 	if (pdata->num_ports <= 0 || pdata->num_ports > DSA_MAX_PORTS) {
353 		dev_err(dev, "invalid number of ports (%d)\n",
354 			pdata->num_ports);
355 		return -EINVAL;
356 	}
357 
358 	/* look for the CPU port */
359 	ofnode_for_each_subnode(pnode, node) {
360 		u32 ethernet;
361 
362 		if (ofnode_read_u32(pnode, "ethernet", &ethernet))
363 			continue;
364 
365 		pdata->master_node = ofnode_get_by_phandle(ethernet);
366 		pdata->cpu_port_node = pnode;
367 		break;
368 	}
369 
370 	if (!ofnode_valid(pdata->master_node)) {
371 		dev_err(dev, "master eth node missing!\n");
372 		return -EINVAL;
373 	}
374 
375 	if (ofnode_read_u32(pnode, "reg", &pdata->cpu_port)) {
376 		dev_err(dev, "CPU port node not valid!\n");
377 		return -EINVAL;
378 	}
379 
380 	dev_dbg(dev, "master node %s on port %d\n",
381 		ofnode_get_name(pdata->master_node), pdata->cpu_port);
382 
383 	for (i = 0; i < pdata->num_ports; i++) {
384 		char name[DSA_PORT_NAME_LENGTH];
385 		struct udevice *pdev;
386 
387 		/*
388 		 * If this is the CPU port don't register it as an ETH device,
389 		 * we skip it on purpose since I/O to/from it from the CPU
390 		 * isn't useful.
391 		 */
392 		if (i == pdata->cpu_port)
393 			continue;
394 
395 		/*
396 		 * Set up default port names.  If present, DT port labels
397 		 * will override the default port names.
398 		 */
399 		snprintf(name, DSA_PORT_NAME_LENGTH, "%s@%d", dev->name, i);
400 
401 		ofnode_for_each_subnode(pnode, node) {
402 			u32 reg;
403 
404 			if (ofnode_read_u32(pnode, "reg", &reg))
405 				continue;
406 
407 			if (reg == i)
408 				break;
409 		}
410 
411 		/*
412 		 * skip registration if port id not found or if the port
413 		 * is explicitly disabled in DT
414 		 */
415 		if (!ofnode_valid(pnode) || !ofnode_is_available(pnode))
416 			continue;
417 
418 		err = device_bind_driver_to_node(dev, DSA_PORT_CHILD_DRV_NAME,
419 						 name, pnode, &pdev);
420 		if (pdev) {
421 			struct dsa_port_pdata *port_pdata;
422 
423 			port_pdata = dev_get_parent_plat(pdev);
424 			strlcpy(port_pdata->name, name, DSA_PORT_NAME_LENGTH);
425 			pdev->name = port_pdata->name;
426 		}
427 
428 		/* try to bind all ports but keep 1st error */
429 		if (err && !first_err)
430 			first_err = err;
431 	}
432 
433 	if (first_err)
434 		return first_err;
435 
436 	dev_dbg(dev, "DSA ports successfully bound\n");
437 
438 	return 0;
439 }
440 
441 /**
442  * Initialize the uclass per device internal state structure (priv).
443  * TODO: pick up references to other switch devices here, if we're cascaded.
444  */
dsa_pre_probe(struct udevice * dev)445 static int dsa_pre_probe(struct udevice *dev)
446 {
447 	struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
448 	struct dsa_priv *priv = dev_get_uclass_priv(dev);
449 
450 	priv->num_ports = pdata->num_ports;
451 	priv->cpu_port = pdata->cpu_port;
452 	priv->cpu_port_fixed_phy = fixed_phy_create(pdata->cpu_port_node);
453 	if (!priv->cpu_port_fixed_phy) {
454 		dev_err(dev, "Failed to register fixed-link for CPU port\n");
455 		return -ENODEV;
456 	}
457 
458 	uclass_find_device_by_ofnode(UCLASS_ETH, pdata->master_node,
459 				     &priv->master_dev);
460 	return 0;
461 }
462 
463 UCLASS_DRIVER(dsa) = {
464 	.id = UCLASS_DSA,
465 	.name = "dsa",
466 	.post_bind = dsa_post_bind,
467 	.pre_probe = dsa_pre_probe,
468 	.per_device_auto = sizeof(struct dsa_priv),
469 	.per_device_plat_auto = sizeof(struct dsa_pdata),
470 	.per_child_plat_auto = sizeof(struct dsa_port_pdata),
471 	.flags = DM_UC_FLAG_SEQ_ALIAS,
472 };
473