xref: /linux/net/dsa/conduit.c (revision 8f7aa3d3c7323f4ca2768a9e74ebbe359c4f8f88)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Handling of a conduit device, switching frames via its switch fabric CPU port
4  *
5  * Copyright (c) 2017 Savoir-faire Linux Inc.
6  *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
7  */
8 
9 #include <linux/ethtool.h>
10 #include <linux/netdevice.h>
11 #include <linux/netlink.h>
12 #include <net/dsa.h>
13 #include <net/netdev_lock.h>
14 
15 #include "conduit.h"
16 #include "dsa.h"
17 #include "port.h"
18 #include "tag.h"
19 
20 static int dsa_conduit_get_regs_len(struct net_device *dev)
21 {
22 	struct dsa_port *cpu_dp = dev->dsa_ptr;
23 	const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
24 	struct dsa_switch *ds = cpu_dp->ds;
25 	int port = cpu_dp->index;
26 	int ret = 0;
27 	int len;
28 
29 	if (ops && ops->get_regs_len) {
30 		netdev_lock_ops(dev);
31 		len = ops->get_regs_len(dev);
32 		netdev_unlock_ops(dev);
33 		if (len < 0)
34 			return len;
35 		ret += len;
36 	}
37 
38 	ret += sizeof(struct ethtool_drvinfo);
39 	ret += sizeof(struct ethtool_regs);
40 
41 	if (ds->ops->get_regs_len) {
42 		len = ds->ops->get_regs_len(ds, port);
43 		if (len < 0)
44 			return len;
45 		ret += len;
46 	}
47 
48 	return ret;
49 }
50 
51 static void dsa_conduit_get_regs(struct net_device *dev,
52 				 struct ethtool_regs *regs, void *data)
53 {
54 	struct dsa_port *cpu_dp = dev->dsa_ptr;
55 	const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
56 	struct dsa_switch *ds = cpu_dp->ds;
57 	struct ethtool_drvinfo *cpu_info;
58 	struct ethtool_regs *cpu_regs;
59 	int port = cpu_dp->index;
60 	int len;
61 
62 	if (ops && ops->get_regs_len && ops->get_regs) {
63 		netdev_lock_ops(dev);
64 		len = ops->get_regs_len(dev);
65 		if (len < 0) {
66 			netdev_unlock_ops(dev);
67 			return;
68 		}
69 		regs->len = len;
70 		ops->get_regs(dev, regs, data);
71 		netdev_unlock_ops(dev);
72 		data += regs->len;
73 	}
74 
75 	cpu_info = (struct ethtool_drvinfo *)data;
76 	strscpy(cpu_info->driver, "dsa", sizeof(cpu_info->driver));
77 	data += sizeof(*cpu_info);
78 	cpu_regs = (struct ethtool_regs *)data;
79 	data += sizeof(*cpu_regs);
80 
81 	if (ds->ops->get_regs_len && ds->ops->get_regs) {
82 		len = ds->ops->get_regs_len(ds, port);
83 		if (len < 0)
84 			return;
85 		cpu_regs->len = len;
86 		ds->ops->get_regs(ds, port, cpu_regs, data);
87 	}
88 }
89 
90 static ssize_t dsa_conduit_append_port_stats(struct dsa_switch *ds, int port,
91 					     u64 *data, size_t start)
92 {
93 	int count;
94 
95 	if (!ds->ops->get_sset_count)
96 		return 0;
97 
98 	count = ds->ops->get_sset_count(ds, port, ETH_SS_STATS);
99 	if (count < 0)
100 		return count;
101 
102 	if (ds->ops->get_ethtool_stats)
103 		ds->ops->get_ethtool_stats(ds, port, data + start);
104 
105 	return count;
106 }
107 
108 static void dsa_conduit_get_ethtool_stats(struct net_device *dev,
109 					  struct ethtool_stats *stats,
110 					  u64 *data)
111 {
112 	struct dsa_port *dp, *cpu_dp = dev->dsa_ptr;
113 	const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
114 	struct dsa_switch_tree *dst = cpu_dp->dst;
115 	int count, mcount = 0;
116 
117 	if (ops && ops->get_sset_count && ops->get_ethtool_stats) {
118 		netdev_lock_ops(dev);
119 		mcount = ops->get_sset_count(dev, ETH_SS_STATS);
120 		ops->get_ethtool_stats(dev, stats, data);
121 		netdev_unlock_ops(dev);
122 	}
123 
124 	list_for_each_entry(dp, &dst->ports, list) {
125 		if (!dsa_port_is_dsa(dp) && !dsa_port_is_cpu(dp))
126 			continue;
127 
128 		count = dsa_conduit_append_port_stats(dp->ds, dp->index,
129 						      data, mcount);
130 		if (count < 0)
131 			return;
132 
133 		mcount += count;
134 	}
135 }
136 
137 static void dsa_conduit_get_ethtool_phy_stats(struct net_device *dev,
138 					      struct ethtool_stats *stats,
139 					      u64 *data)
140 {
141 	struct dsa_port *cpu_dp = dev->dsa_ptr;
142 	const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
143 	struct dsa_switch *ds = cpu_dp->ds;
144 	int port = cpu_dp->index;
145 	int count = 0;
146 
147 	if (dev->phydev && (!ops || !ops->get_ethtool_phy_stats)) {
148 		count = phy_ethtool_get_sset_count(dev->phydev);
149 		if (count >= 0)
150 			phy_ethtool_get_stats(dev->phydev, stats, data);
151 	} else if (ops && ops->get_sset_count && ops->get_ethtool_phy_stats) {
152 		netdev_lock_ops(dev);
153 		count = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
154 		ops->get_ethtool_phy_stats(dev, stats, data);
155 		netdev_unlock_ops(dev);
156 	}
157 
158 	if (count < 0)
159 		count = 0;
160 
161 	if (ds->ops->get_ethtool_phy_stats)
162 		ds->ops->get_ethtool_phy_stats(ds, port, data + count);
163 }
164 
165 static void dsa_conduit_append_port_sset_count(struct dsa_switch *ds, int port,
166 					       int sset, int *count)
167 {
168 	if (ds->ops->get_sset_count)
169 		*count += ds->ops->get_sset_count(ds, port, sset);
170 }
171 
172 static int dsa_conduit_get_sset_count(struct net_device *dev, int sset)
173 {
174 	struct dsa_port *dp, *cpu_dp = dev->dsa_ptr;
175 	const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
176 	struct dsa_switch_tree *dst = cpu_dp->dst;
177 	int count = 0;
178 
179 	netdev_lock_ops(dev);
180 	if (sset == ETH_SS_PHY_STATS && dev->phydev &&
181 	    (!ops || !ops->get_ethtool_phy_stats))
182 		count = phy_ethtool_get_sset_count(dev->phydev);
183 	else if (ops && ops->get_sset_count)
184 		count = ops->get_sset_count(dev, sset);
185 	netdev_unlock_ops(dev);
186 
187 	if (count < 0)
188 		count = 0;
189 
190 	list_for_each_entry(dp, &dst->ports, list) {
191 		if (!dsa_port_is_dsa(dp) && !dsa_port_is_cpu(dp))
192 			continue;
193 
194 		dsa_conduit_append_port_sset_count(dp->ds, dp->index, sset,
195 						   &count);
196 	}
197 
198 	return count;
199 }
200 
201 static ssize_t dsa_conduit_append_port_strings(struct dsa_switch *ds, int port,
202 					       u32 stringset, u8 *data,
203 					       size_t start)
204 {
205 	int len = ETH_GSTRING_LEN;
206 	u8 pfx[8], *ndata;
207 	int count, i;
208 
209 	if (!ds->ops->get_strings)
210 		return 0;
211 
212 	snprintf(pfx, sizeof(pfx), "s%.2d_p%.2d", ds->index, port);
213 	/* We do not want to be NULL-terminated, since this is a prefix */
214 	pfx[sizeof(pfx) - 1] = '_';
215 	ndata = data + start * len;
216 	/* This function copies ETH_GSTRINGS_LEN bytes, we will mangle
217 	 * the output after to prepend our CPU port prefix we
218 	 * constructed earlier
219 	 */
220 	ds->ops->get_strings(ds, port, stringset, ndata);
221 	count = ds->ops->get_sset_count(ds, port, stringset);
222 	if (count < 0)
223 		return count;
224 
225 	for (i = 0; i < count; i++) {
226 		memmove(ndata + (i * len + sizeof(pfx)),
227 			ndata + i * len, len - sizeof(pfx));
228 		memcpy(ndata + i * len, pfx, sizeof(pfx));
229 	}
230 
231 	return count;
232 }
233 
234 static void dsa_conduit_get_strings(struct net_device *dev, u32 stringset,
235 				    u8 *data)
236 {
237 	struct dsa_port *dp, *cpu_dp = dev->dsa_ptr;
238 	const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;
239 	struct dsa_switch_tree *dst = cpu_dp->dst;
240 	int count, mcount = 0;
241 
242 	netdev_lock_ops(dev);
243 	if (stringset == ETH_SS_PHY_STATS && dev->phydev &&
244 	    !ops->get_ethtool_phy_stats) {
245 		mcount = phy_ethtool_get_sset_count(dev->phydev);
246 		if (mcount < 0)
247 			mcount = 0;
248 		else
249 			phy_ethtool_get_strings(dev->phydev, data);
250 	} else if (ops->get_sset_count && ops->get_strings) {
251 		mcount = ops->get_sset_count(dev, stringset);
252 		if (mcount < 0)
253 			mcount = 0;
254 		ops->get_strings(dev, stringset, data);
255 	}
256 	netdev_unlock_ops(dev);
257 
258 	list_for_each_entry(dp, &dst->ports, list) {
259 		if (!dsa_port_is_dsa(dp) && !dsa_port_is_cpu(dp))
260 			continue;
261 
262 		count = dsa_conduit_append_port_strings(dp->ds, dp->index,
263 							stringset, data,
264 							mcount);
265 		if (count < 0)
266 			return;
267 
268 		mcount += count;
269 	}
270 }
271 
272 /* Deny PTP operations on conduit if there is at least one switch in the tree
273  * that is PTP capable.
274  */
275 int __dsa_conduit_hwtstamp_validate(struct net_device *dev,
276 				    const struct kernel_hwtstamp_config *config,
277 				    struct netlink_ext_ack *extack)
278 {
279 	struct dsa_port *cpu_dp = dev->dsa_ptr;
280 	struct dsa_switch *ds = cpu_dp->ds;
281 	struct dsa_switch_tree *dst;
282 	struct dsa_port *dp;
283 
284 	dst = ds->dst;
285 
286 	list_for_each_entry(dp, &dst->ports, list) {
287 		if (dsa_port_supports_hwtstamp(dp)) {
288 			NL_SET_ERR_MSG(extack,
289 				       "HW timestamping not allowed on DSA conduit when switch supports the operation");
290 			return -EBUSY;
291 		}
292 	}
293 
294 	return 0;
295 }
296 
297 static int dsa_conduit_ethtool_setup(struct net_device *dev)
298 {
299 	struct dsa_port *cpu_dp = dev->dsa_ptr;
300 	struct dsa_switch *ds = cpu_dp->ds;
301 	struct ethtool_ops *ops;
302 
303 	if (netif_is_lag_master(dev))
304 		return 0;
305 
306 	ops = devm_kzalloc(ds->dev, sizeof(*ops), GFP_KERNEL);
307 	if (!ops)
308 		return -ENOMEM;
309 
310 	cpu_dp->orig_ethtool_ops = dev->ethtool_ops;
311 	if (cpu_dp->orig_ethtool_ops)
312 		memcpy(ops, cpu_dp->orig_ethtool_ops, sizeof(*ops));
313 
314 	ops->get_regs_len = dsa_conduit_get_regs_len;
315 	ops->get_regs = dsa_conduit_get_regs;
316 	ops->get_sset_count = dsa_conduit_get_sset_count;
317 	ops->get_ethtool_stats = dsa_conduit_get_ethtool_stats;
318 	ops->get_strings = dsa_conduit_get_strings;
319 	ops->get_ethtool_phy_stats = dsa_conduit_get_ethtool_phy_stats;
320 
321 	dev->ethtool_ops = ops;
322 
323 	return 0;
324 }
325 
326 static void dsa_conduit_ethtool_teardown(struct net_device *dev)
327 {
328 	struct dsa_port *cpu_dp = dev->dsa_ptr;
329 
330 	if (netif_is_lag_master(dev))
331 		return;
332 
333 	dev->ethtool_ops = cpu_dp->orig_ethtool_ops;
334 	cpu_dp->orig_ethtool_ops = NULL;
335 }
336 
337 /* Keep the conduit always promiscuous if the tagging protocol requires that
338  * (garbles MAC DA) or if it doesn't support unicast filtering, case in which
339  * it would revert to promiscuous mode as soon as we call dev_uc_add() on it
340  * anyway.
341  */
342 static void dsa_conduit_set_promiscuity(struct net_device *dev, int inc)
343 {
344 	const struct dsa_device_ops *ops = dev->dsa_ptr->tag_ops;
345 
346 	if ((dev->priv_flags & IFF_UNICAST_FLT) && !ops->promisc_on_conduit)
347 		return;
348 
349 	ASSERT_RTNL();
350 
351 	dev_set_promiscuity(dev, inc);
352 }
353 
354 static ssize_t tagging_show(struct device *d, struct device_attribute *attr,
355 			    char *buf)
356 {
357 	struct net_device *dev = to_net_dev(d);
358 	struct dsa_port *cpu_dp = dev->dsa_ptr;
359 
360 	return sysfs_emit(buf, "%s\n",
361 		       dsa_tag_protocol_to_str(cpu_dp->tag_ops));
362 }
363 
364 static ssize_t tagging_store(struct device *d, struct device_attribute *attr,
365 			     const char *buf, size_t count)
366 {
367 	const struct dsa_device_ops *new_tag_ops, *old_tag_ops;
368 	const char *end = strchrnul(buf, '\n'), *name;
369 	struct net_device *dev = to_net_dev(d);
370 	struct dsa_port *cpu_dp = dev->dsa_ptr;
371 	size_t len = end - buf;
372 	int err;
373 
374 	/* Empty string passed */
375 	if (!len)
376 		return -ENOPROTOOPT;
377 
378 	name = kstrndup(buf, len, GFP_KERNEL);
379 	if (!name)
380 		return -ENOMEM;
381 
382 	old_tag_ops = cpu_dp->tag_ops;
383 	new_tag_ops = dsa_tag_driver_get_by_name(name);
384 	kfree(name);
385 	/* Bad tagger name? */
386 	if (IS_ERR(new_tag_ops))
387 		return PTR_ERR(new_tag_ops);
388 
389 	if (new_tag_ops == old_tag_ops)
390 		/* Drop the temporarily held duplicate reference, since
391 		 * the DSA switch tree uses this tagger.
392 		 */
393 		goto out;
394 
395 	err = dsa_tree_change_tag_proto(cpu_dp->ds->dst, new_tag_ops,
396 					old_tag_ops);
397 	if (err) {
398 		/* On failure the old tagger is restored, so we don't need the
399 		 * driver for the new one.
400 		 */
401 		dsa_tag_driver_put(new_tag_ops);
402 		return err;
403 	}
404 
405 	/* On success we no longer need the module for the old tagging protocol
406 	 */
407 out:
408 	dsa_tag_driver_put(old_tag_ops);
409 	return count;
410 }
411 static DEVICE_ATTR_RW(tagging);
412 
413 static struct attribute *dsa_user_attrs[] = {
414 	&dev_attr_tagging.attr,
415 	NULL
416 };
417 
418 static const struct attribute_group dsa_group = {
419 	.name	= "dsa",
420 	.attrs	= dsa_user_attrs,
421 };
422 
423 static void dsa_conduit_reset_mtu(struct net_device *dev)
424 {
425 	int err;
426 
427 	err = dev_set_mtu(dev, ETH_DATA_LEN);
428 	if (err)
429 		netdev_dbg(dev,
430 			   "Unable to reset MTU to exclude DSA overheads\n");
431 }
432 
433 int dsa_conduit_setup(struct net_device *dev, struct dsa_port *cpu_dp)
434 {
435 	const struct dsa_device_ops *tag_ops = cpu_dp->tag_ops;
436 	struct dsa_switch *ds = cpu_dp->ds;
437 	struct device_link *consumer_link;
438 	int mtu, ret;
439 
440 	mtu = ETH_DATA_LEN + dsa_tag_protocol_overhead(tag_ops);
441 
442 	/* The DSA conduit must use SET_NETDEV_DEV for this to work. */
443 	if (!netif_is_lag_master(dev)) {
444 		consumer_link = device_link_add(ds->dev, dev->dev.parent,
445 						DL_FLAG_AUTOREMOVE_CONSUMER);
446 		if (!consumer_link)
447 			netdev_err(dev,
448 				   "Failed to create a device link to DSA switch %s\n",
449 				   dev_name(ds->dev));
450 	}
451 
452 	/* The switch driver may not implement ->port_change_mtu(), case in
453 	 * which dsa_user_change_mtu() will not update the conduit MTU either,
454 	 * so we need to do that here.
455 	 */
456 	ret = dev_set_mtu(dev, mtu);
457 	if (ret)
458 		netdev_warn(dev, "error %d setting MTU to %d to include DSA overhead\n",
459 			    ret, mtu);
460 
461 	/* If we use a tagging format that doesn't have an ethertype
462 	 * field, make sure that all packets from this point on get
463 	 * sent to the tag format's receive function.
464 	 */
465 	wmb();
466 
467 	dev->dsa_ptr = cpu_dp;
468 
469 	dsa_conduit_set_promiscuity(dev, 1);
470 
471 	ret = dsa_conduit_ethtool_setup(dev);
472 	if (ret)
473 		goto out_err_reset_promisc;
474 
475 	ret = sysfs_create_group(&dev->dev.kobj, &dsa_group);
476 	if (ret)
477 		goto out_err_ethtool_teardown;
478 
479 	return ret;
480 
481 out_err_ethtool_teardown:
482 	dsa_conduit_ethtool_teardown(dev);
483 out_err_reset_promisc:
484 	dsa_conduit_set_promiscuity(dev, -1);
485 	return ret;
486 }
487 
488 void dsa_conduit_teardown(struct net_device *dev)
489 {
490 	sysfs_remove_group(&dev->dev.kobj, &dsa_group);
491 	dsa_conduit_ethtool_teardown(dev);
492 	dsa_conduit_reset_mtu(dev);
493 	dsa_conduit_set_promiscuity(dev, -1);
494 
495 	dev->dsa_ptr = NULL;
496 
497 	/* If we used a tagging format that doesn't have an ethertype
498 	 * field, make sure that all packets from this point get sent
499 	 * without the tag and go through the regular receive path.
500 	 */
501 	wmb();
502 }
503 
504 int dsa_conduit_lag_setup(struct net_device *lag_dev, struct dsa_port *cpu_dp,
505 			  struct netdev_lag_upper_info *uinfo,
506 			  struct netlink_ext_ack *extack)
507 {
508 	bool conduit_setup = false;
509 	int err;
510 
511 	if (!netdev_uses_dsa(lag_dev)) {
512 		err = dsa_conduit_setup(lag_dev, cpu_dp);
513 		if (err)
514 			return err;
515 
516 		conduit_setup = true;
517 	}
518 
519 	err = dsa_port_lag_join(cpu_dp, lag_dev, uinfo, extack);
520 	if (err) {
521 		NL_SET_ERR_MSG_WEAK_MOD(extack, "CPU port failed to join LAG");
522 		goto out_conduit_teardown;
523 	}
524 
525 	return 0;
526 
527 out_conduit_teardown:
528 	if (conduit_setup)
529 		dsa_conduit_teardown(lag_dev);
530 	return err;
531 }
532 
533 /* Tear down a conduit if there isn't any other user port on it,
534  * optionally also destroying LAG information.
535  */
536 void dsa_conduit_lag_teardown(struct net_device *lag_dev,
537 			      struct dsa_port *cpu_dp)
538 {
539 	struct net_device *upper;
540 	struct list_head *iter;
541 
542 	dsa_port_lag_leave(cpu_dp, lag_dev);
543 
544 	netdev_for_each_upper_dev_rcu(lag_dev, upper, iter)
545 		if (dsa_user_dev_check(upper))
546 			return;
547 
548 	dsa_conduit_teardown(lag_dev);
549 }
550