dsa2.c 17.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-or-later
2 3 4 5 6 7 8 9 10 11
/*
 * net/dsa/dsa2.c - Hardware switch handling, binding version 2
 * Copyright (c) 2008-2009 Marvell Semiconductor
 * Copyright (c) 2013 Florian Fainelli <florian@openwrt.org>
 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
 */

#include <linux/device.h>
#include <linux/err.h>
#include <linux/list.h>
12
#include <linux/netdevice.h>
13 14 15 16
#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/of.h>
#include <linux/of_net.h>
17
#include <net/devlink.h>
18

19 20
#include "dsa_priv.h"

21
static LIST_HEAD(dsa_tree_list);
22 23
static DEFINE_MUTEX(dsa2_mutex);

24 25 26
static const struct devlink_ops dsa_devlink_ops = {
};

27
static struct dsa_switch_tree *dsa_tree_find(int index)
28 29 30
{
	struct dsa_switch_tree *dst;

31
	list_for_each_entry(dst, &dsa_tree_list, list)
32
		if (dst->index == index)
33
			return dst;
34

35 36 37
	return NULL;
}

38
static struct dsa_switch_tree *dsa_tree_alloc(int index)
39 40 41 42 43 44
{
	struct dsa_switch_tree *dst;

	dst = kzalloc(sizeof(*dst), GFP_KERNEL);
	if (!dst)
		return NULL;
45

46
	dst->index = index;
47

48
	INIT_LIST_HEAD(&dst->list);
49
	list_add_tail(&dsa_tree_list, &dst->list);
50

51 52 53 54 55
	kref_init(&dst->refcount);

	return dst;
}

56 57 58 59 60 61
static void dsa_tree_free(struct dsa_switch_tree *dst)
{
	list_del(&dst->list);
	kfree(dst);
}

62
static struct dsa_switch_tree *dsa_tree_get(struct dsa_switch_tree *dst)
63
{
64 65
	if (dst)
		kref_get(&dst->refcount);
66 67 68 69

	return dst;
}

70
static struct dsa_switch_tree *dsa_tree_touch(int index)
71
{
72 73 74 75 76 77 78
	struct dsa_switch_tree *dst;

	dst = dsa_tree_find(index);
	if (dst)
		return dsa_tree_get(dst);
	else
		return dsa_tree_alloc(index);
79 80 81 82 83 84 85 86 87 88 89 90 91
}

static void dsa_tree_release(struct kref *ref)
{
	struct dsa_switch_tree *dst;

	dst = container_of(ref, struct dsa_switch_tree, refcount);

	dsa_tree_free(dst);
}

static void dsa_tree_put(struct dsa_switch_tree *dst)
{
92 93
	if (dst)
		kref_put(&dst->refcount, dsa_tree_release);
94 95
}

96
static bool dsa_port_is_dsa(struct dsa_port *port)
97
{
98
	return port->type == DSA_PORT_TYPE_DSA;
99 100 101 102
}

static bool dsa_port_is_cpu(struct dsa_port *port)
{
103
	return port->type == DSA_PORT_TYPE_CPU;
104 105
}

106 107 108 109 110
static bool dsa_port_is_user(struct dsa_port *dp)
{
	return dp->type == DSA_PORT_TYPE_USER;
}

111 112
static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst,
						   struct device_node *dn)
113 114
{
	struct dsa_switch *ds;
115 116
	struct dsa_port *dp;
	int device, port;
117

118 119
	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
		ds = dst->ds[device];
120 121 122
		if (!ds)
			continue;

123 124 125 126 127 128
		for (port = 0; port < ds->num_ports; port++) {
			dp = &ds->ports[port];

			if (dp->dn == dn)
				return dp;
		}
129 130 131 132 133
	}

	return NULL;
}

V
Vivien Didelot 已提交
134
static bool dsa_port_setup_routing_table(struct dsa_port *dp)
135
{
V
Vivien Didelot 已提交
136 137 138
	struct dsa_switch *ds = dp->ds;
	struct dsa_switch_tree *dst = ds->dst;
	struct device_node *dn = dp->dn;
V
Vivien Didelot 已提交
139
	struct of_phandle_iterator it;
140
	struct dsa_port *link_dp;
V
Vivien Didelot 已提交
141
	int err;
142

V
Vivien Didelot 已提交
143 144 145 146
	of_for_each_phandle(&it, err, dn, "link", NULL, 0) {
		link_dp = dsa_tree_find_port_by_node(dst, it.node);
		if (!link_dp) {
			of_node_put(it.node);
V
Vivien Didelot 已提交
147
			return false;
V
Vivien Didelot 已提交
148
		}
149

V
Vivien Didelot 已提交
150
		ds->rtable[link_dp->ds->index] = dp->index;
151 152
	}

V
Vivien Didelot 已提交
153
	return true;
154 155
}

V
Vivien Didelot 已提交
156
static bool dsa_switch_setup_routing_table(struct dsa_switch *ds)
157
{
V
Vivien Didelot 已提交
158 159 160
	bool complete = true;
	struct dsa_port *dp;
	int i;
161

V
Vivien Didelot 已提交
162 163
	for (i = 0; i < DSA_MAX_SWITCHES; i++)
		ds->rtable[i] = DSA_RTABLE_NONE;
164

V
Vivien Didelot 已提交
165 166
	for (i = 0; i < ds->num_ports; i++) {
		dp = &ds->ports[i];
167

V
Vivien Didelot 已提交
168 169 170 171 172
		if (dsa_port_is_dsa(dp)) {
			complete = dsa_port_setup_routing_table(dp);
			if (!complete)
				break;
		}
173 174
	}

V
Vivien Didelot 已提交
175
	return complete;
176 177
}

V
Vivien Didelot 已提交
178
static bool dsa_tree_setup_routing_table(struct dsa_switch_tree *dst)
179 180
{
	struct dsa_switch *ds;
V
Vivien Didelot 已提交
181 182
	bool complete = true;
	int device;
183

V
Vivien Didelot 已提交
184 185
	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
		ds = dst->ds[device];
186 187 188
		if (!ds)
			continue;

V
Vivien Didelot 已提交
189 190 191
		complete = dsa_switch_setup_routing_table(ds);
		if (!complete)
			break;
192 193
	}

V
Vivien Didelot 已提交
194
	return complete;
195 196
}

197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst)
{
	struct dsa_switch *ds;
	struct dsa_port *dp;
	int device, port;

	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
		ds = dst->ds[device];
		if (!ds)
			continue;

		for (port = 0; port < ds->num_ports; port++) {
			dp = &ds->ports[port];

			if (dsa_port_is_cpu(dp))
				return dp;
		}
	}

	return NULL;
}

static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst)
{
	struct dsa_switch *ds;
	struct dsa_port *dp;
	int device, port;

	/* DSA currently only supports a single CPU port */
	dst->cpu_dp = dsa_tree_find_first_cpu(dst);
	if (!dst->cpu_dp) {
		pr_warn("Tree has no master device\n");
		return -EINVAL;
	}

	/* Assign the default CPU port to all ports of the fabric */
	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
		ds = dst->ds[device];
		if (!ds)
			continue;

		for (port = 0; port < ds->num_ports; port++) {
			dp = &ds->ports[port];

241
			if (dsa_port_is_user(dp) || dsa_port_is_dsa(dp))
242 243 244 245 246 247 248 249 250 251 252 253 254
				dp->cpu_dp = dst->cpu_dp;
		}
	}

	return 0;
}

static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst)
{
	/* DSA currently only supports a single CPU port */
	dst->cpu_dp = NULL;
}

255
static int dsa_port_setup(struct dsa_port *dp)
256
{
257
	enum devlink_port_flavour flavour;
258
	struct dsa_switch *ds = dp->ds;
259
	struct dsa_switch_tree *dst = ds->dst;
260
	int err = 0;
261 262 263

	if (dp->type == DSA_PORT_TYPE_UNUSED)
		return 0;
264

265
	memset(&dp->devlink_port, 0, sizeof(dp->devlink_port));
266
	dp->mac = of_get_mac_address(dp->dn);
267

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
	switch (dp->type) {
	case DSA_PORT_TYPE_CPU:
		flavour = DEVLINK_PORT_FLAVOUR_CPU;
		break;
	case DSA_PORT_TYPE_DSA:
		flavour = DEVLINK_PORT_FLAVOUR_DSA;
		break;
	case DSA_PORT_TYPE_USER: /* fall-through */
	default:
		flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
		break;
	}

	/* dp->index is used now as port_number. However
	 * CPU and DSA ports should have separate numbering
	 * independent from front panel port numbers.
	 */
	devlink_port_attrs_set(&dp->devlink_port, flavour,
286 287
			       dp->index, false, 0,
			       (const char *) &dst->index, sizeof(dst->index));
288 289
	err = devlink_port_register(ds->devlink, &dp->devlink_port,
				    dp->index);
290
	if (err)
291 292
		return err;

293 294 295 296
	switch (dp->type) {
	case DSA_PORT_TYPE_UNUSED:
		break;
	case DSA_PORT_TYPE_CPU:
297
		err = dsa_port_link_register_of(dp);
298
		if (err)
299 300 301
			dev_err(ds->dev, "failed to setup link for port %d.%d\n",
				ds->index, dp->index);
		break;
302
	case DSA_PORT_TYPE_DSA:
303
		err = dsa_port_link_register_of(dp);
304
		if (err)
305
			dev_err(ds->dev, "failed to setup link for port %d.%d\n",
306 307 308 309 310 311 312 313 314 315
				ds->index, dp->index);
		break;
	case DSA_PORT_TYPE_USER:
		err = dsa_slave_create(dp);
		if (err)
			dev_err(ds->dev, "failed to create slave for port %d.%d\n",
				ds->index, dp->index);
		else
			devlink_port_type_eth_set(&dp->devlink_port, dp->slave);
		break;
316 317
	}

318 319 320 321
	if (err)
		devlink_port_unregister(&dp->devlink_port);

	return err;
322 323
}

324
static void dsa_port_teardown(struct dsa_port *dp)
325
{
326 327
	if (dp->type != DSA_PORT_TYPE_UNUSED)
		devlink_port_unregister(&dp->devlink_port);
328 329 330 331 332

	switch (dp->type) {
	case DSA_PORT_TYPE_UNUSED:
		break;
	case DSA_PORT_TYPE_CPU:
333 334
		dsa_tag_driver_put(dp->tag_ops);
		/* fall-through */
335
	case DSA_PORT_TYPE_DSA:
336
		dsa_port_link_unregister_of(dp);
337 338 339 340 341 342 343
		break;
	case DSA_PORT_TYPE_USER:
		if (dp->slave) {
			dsa_slave_destroy(dp->slave);
			dp->slave = NULL;
		}
		break;
344 345 346
	}
}

347
static int dsa_switch_setup(struct dsa_switch *ds)
348
{
349
	int err = 0;
350

351
	/* Initialize ds->phys_mii_mask before registering the slave MDIO bus
352
	 * driver and before ops->setup() has run, since the switch drivers and
353 354 355
	 * the slave MDIO bus driver rely on these values for probing PHY
	 * devices or not
	 */
356
	ds->phys_mii_mask |= dsa_user_ports(ds);
357

358 359 360 361 362 363 364 365 366
	/* Add the switch to devlink before calling setup, so that setup can
	 * add dpipe tables
	 */
	ds->devlink = devlink_alloc(&dsa_devlink_ops, 0);
	if (!ds->devlink)
		return -ENOMEM;

	err = devlink_register(ds->devlink, ds->dev);
	if (err)
367
		goto free_devlink;
368

V
Vivien Didelot 已提交
369 370
	err = dsa_switch_register_notifier(ds);
	if (err)
371
		goto unregister_devlink;
V
Vivien Didelot 已提交
372

373 374
	err = ds->ops->setup(ds);
	if (err < 0)
375
		goto unregister_notifier;
376

377
	if (!ds->slave_mii_bus && ds->ops->phy_read) {
378
		ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
379 380 381 382
		if (!ds->slave_mii_bus) {
			err = -ENOMEM;
			goto unregister_notifier;
		}
383 384 385 386 387

		dsa_slave_mii_bus_init(ds);

		err = mdiobus_register(ds->slave_mii_bus);
		if (err < 0)
388
			goto unregister_notifier;
389 390
	}

391
	return 0;
392 393 394 395 396 397 398 399 400 401

unregister_notifier:
	dsa_switch_unregister_notifier(ds);
unregister_devlink:
	devlink_unregister(ds->devlink);
free_devlink:
	devlink_free(ds->devlink);
	ds->devlink = NULL;

	return err;
402 403
}

404
static void dsa_switch_teardown(struct dsa_switch *ds)
405
{
406
	if (ds->slave_mii_bus && ds->ops->phy_read)
407
		mdiobus_unregister(ds->slave_mii_bus);
V
Vivien Didelot 已提交
408 409

	dsa_switch_unregister_notifier(ds);
410

411 412 413
	if (ds->ops->teardown)
		ds->ops->teardown(ds);

414 415 416 417 418 419
	if (ds->devlink) {
		devlink_unregister(ds->devlink);
		devlink_free(ds->devlink);
		ds->devlink = NULL;
	}

420 421
}

422 423 424
static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
{
	struct dsa_switch *ds;
425
	struct dsa_port *dp;
426 427
	int device, port, i;
	int err = 0;
428 429 430 431 432 433 434 435

	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
		ds = dst->ds[device];
		if (!ds)
			continue;

		err = dsa_switch_setup(ds);
		if (err)
436
			goto switch_teardown;
437 438 439 440 441 442

		for (port = 0; port < ds->num_ports; port++) {
			dp = &ds->ports[port];

			err = dsa_port_setup(dp);
			if (err)
443
				goto ports_teardown;
444
		}
445 446 447
	}

	return 0;
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470

ports_teardown:
	for (i = 0; i < port; i++)
		dsa_port_teardown(&ds->ports[i]);

	dsa_switch_teardown(ds);

switch_teardown:
	for (i = 0; i < device; i++) {
		ds = dst->ds[i];
		if (!ds)
			continue;

		for (port = 0; port < ds->num_ports; port++) {
			dp = &ds->ports[port];

			dsa_port_teardown(dp);
		}

		dsa_switch_teardown(ds);
	}

	return err;
471 472 473 474 475
}

static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst)
{
	struct dsa_switch *ds;
476 477
	struct dsa_port *dp;
	int device, port;
478 479 480 481 482 483

	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
		ds = dst->ds[device];
		if (!ds)
			continue;

484 485 486 487 488 489
		for (port = 0; port < ds->num_ports; port++) {
			dp = &ds->ports[port];

			dsa_port_teardown(dp);
		}

490 491 492 493
		dsa_switch_teardown(ds);
	}
}

494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
static int dsa_tree_setup_master(struct dsa_switch_tree *dst)
{
	struct dsa_port *cpu_dp = dst->cpu_dp;
	struct net_device *master = cpu_dp->master;

	/* DSA currently supports a single pair of CPU port and master device */
	return dsa_master_setup(master, cpu_dp);
}

static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
{
	struct dsa_port *cpu_dp = dst->cpu_dp;
	struct net_device *master = cpu_dp->master;

	return dsa_master_teardown(master);
}

V
Vivien Didelot 已提交
511
static int dsa_tree_setup(struct dsa_switch_tree *dst)
512
{
V
Vivien Didelot 已提交
513
	bool complete;
514 515
	int err;

V
Vivien Didelot 已提交
516 517 518 519 520 521
	if (dst->setup) {
		pr_err("DSA: tree %d already setup! Disjoint trees?\n",
		       dst->index);
		return -EEXIST;
	}

V
Vivien Didelot 已提交
522 523 524 525
	complete = dsa_tree_setup_routing_table(dst);
	if (!complete)
		return 0;

526 527 528 529
	err = dsa_tree_setup_default_cpu(dst);
	if (err)
		return err;

530 531
	err = dsa_tree_setup_switches(dst);
	if (err)
532
		goto teardown_default_cpu;
533

534
	err = dsa_tree_setup_master(dst);
535
	if (err)
536
		goto teardown_switches;
537

V
Vivien Didelot 已提交
538 539 540
	dst->setup = true;

	pr_info("DSA: tree %d setup\n", dst->index);
541 542

	return 0;
543 544 545 546 547 548 549

teardown_switches:
	dsa_tree_teardown_switches(dst);
teardown_default_cpu:
	dsa_tree_teardown_default_cpu(dst);

	return err;
550 551
}

V
Vivien Didelot 已提交
552
static void dsa_tree_teardown(struct dsa_switch_tree *dst)
553
{
V
Vivien Didelot 已提交
554
	if (!dst->setup)
555 556
		return;

557
	dsa_tree_teardown_master(dst);
558

559
	dsa_tree_teardown_switches(dst);
560

561
	dsa_tree_teardown_default_cpu(dst);
562

V
Vivien Didelot 已提交
563 564 565
	pr_info("DSA: tree %d torn down\n", dst->index);

	dst->setup = false;
566 567
}

568 569 570
static void dsa_tree_remove_switch(struct dsa_switch_tree *dst,
				   unsigned int index)
{
571 572
	dsa_tree_teardown(dst);

573 574 575 576 577 578 579 580
	dst->ds[index] = NULL;
	dsa_tree_put(dst);
}

static int dsa_tree_add_switch(struct dsa_switch_tree *dst,
			       struct dsa_switch *ds)
{
	unsigned int index = ds->index;
581
	int err;
582 583 584 585 586 587 588

	if (dst->ds[index])
		return -EBUSY;

	dsa_tree_get(dst);
	dst->ds[index] = ds;

589
	err = dsa_tree_setup(dst);
590 591 592 593
	if (err) {
		dst->ds[index] = NULL;
		dsa_tree_put(dst);
	}
594 595

	return err;
596 597
}

598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
static int dsa_port_parse_user(struct dsa_port *dp, const char *name)
{
	if (!name)
		name = "eth%d";

	dp->type = DSA_PORT_TYPE_USER;
	dp->name = name;

	return 0;
}

static int dsa_port_parse_dsa(struct dsa_port *dp)
{
	dp->type = DSA_PORT_TYPE_DSA;

	return 0;
}

static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master)
{
618 619 620 621 622
	struct dsa_switch *ds = dp->ds;
	struct dsa_switch_tree *dst = ds->dst;
	const struct dsa_device_ops *tag_ops;
	enum dsa_tag_protocol tag_protocol;

623
	tag_protocol = ds->ops->get_tag_protocol(ds, dp->index);
624
	tag_ops = dsa_tag_driver_get(tag_protocol);
625 626 627 628 629
	if (IS_ERR(tag_ops)) {
		dev_warn(ds->dev, "No tagger for this switch\n");
		return PTR_ERR(tag_ops);
	}

630
	dp->type = DSA_PORT_TYPE_CPU;
631
	dp->filter = tag_ops->filter;
632 633
	dp->rcv = tag_ops->rcv;
	dp->tag_ops = tag_ops;
634
	dp->master = master;
635
	dp->dst = dst;
636 637 638 639

	return 0;
}

640 641
static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
{
642
	struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0);
643
	const char *name = of_get_property(dn, "label", NULL);
644
	bool link = of_property_read_bool(dn, "link");
645

646 647
	dp->dn = dn;

648
	if (ethernet) {
649 650 651 652 653 654
		struct net_device *master;

		master = of_find_net_device_by_node(ethernet);
		if (!master)
			return -EPROBE_DEFER;

655
		return dsa_port_parse_cpu(dp, master);
656 657
	}

658 659
	if (link)
		return dsa_port_parse_dsa(dp);
660

661
	return dsa_port_parse_user(dp, name);
662 663
}

V
Vivien Didelot 已提交
664 665
static int dsa_switch_parse_ports_of(struct dsa_switch *ds,
				     struct device_node *dn)
666
{
667
	struct device_node *ports, *port;
668
	struct dsa_port *dp;
669
	int err = 0;
670
	u32 reg;
671 672 673 674 675 676

	ports = of_get_child_by_name(dn, "ports");
	if (!ports) {
		dev_err(ds->dev, "no ports child node found\n");
		return -EINVAL;
	}
677 678 679 680

	for_each_available_child_of_node(ports, port) {
		err = of_property_read_u32(port, "reg", &reg);
		if (err)
681
			goto out_put_node;
682

683 684 685 686
		if (reg >= ds->num_ports) {
			err = -EINVAL;
			goto out_put_node;
		}
687

688 689 690 691
		dp = &ds->ports[reg];

		err = dsa_port_parse_of(dp, port);
		if (err)
692
			goto out_put_node;
693 694
	}

695 696 697
out_put_node:
	of_node_put(ports);
	return err;
698 699
}

V
Vivien Didelot 已提交
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
static int dsa_switch_parse_member_of(struct dsa_switch *ds,
				      struct device_node *dn)
{
	u32 m[2] = { 0, 0 };
	int sz;

	/* Don't error out if this optional property isn't found */
	sz = of_property_read_variable_u32_array(dn, "dsa,member", m, 2, 2);
	if (sz < 0 && sz != -EINVAL)
		return sz;

	ds->index = m[1];
	if (ds->index >= DSA_MAX_SWITCHES)
		return -EINVAL;

	ds->dst = dsa_tree_touch(m[0]);
	if (!ds->dst)
		return -ENOMEM;

	return 0;
}

static int dsa_switch_parse_of(struct dsa_switch *ds, struct device_node *dn)
{
	int err;

	err = dsa_switch_parse_member_of(ds, dn);
	if (err)
		return err;

	return dsa_switch_parse_ports_of(ds, dn);
}

733 734 735
static int dsa_port_parse(struct dsa_port *dp, const char *name,
			  struct device *dev)
{
736
	if (!strcmp(name, "cpu")) {
737 738 739 740 741 742 743 744
		struct net_device *master;

		master = dsa_dev_to_net_device(dev);
		if (!master)
			return -EPROBE_DEFER;

		dev_put(master);

745
		return dsa_port_parse_cpu(dp, master);
746 747
	}

748 749
	if (!strcmp(name, "dsa"))
		return dsa_port_parse_dsa(dp);
750

751
	return dsa_port_parse_user(dp, name);
752 753
}

V
Vivien Didelot 已提交
754 755
static int dsa_switch_parse_ports(struct dsa_switch *ds,
				  struct dsa_chip_data *cd)
756 757
{
	bool valid_name_found = false;
758 759 760
	struct dsa_port *dp;
	struct device *dev;
	const char *name;
761
	unsigned int i;
762
	int err;
763 764

	for (i = 0; i < DSA_MAX_PORTS; i++) {
765 766 767 768 769
		name = cd->port_names[i];
		dev = cd->netdev[i];
		dp = &ds->ports[i];

		if (!name)
770 771
			continue;

772 773 774 775
		err = dsa_port_parse(dp, name, dev);
		if (err)
			return err;

776 777 778 779 780 781 782 783 784
		valid_name_found = true;
	}

	if (!valid_name_found && i == DSA_MAX_PORTS)
		return -EINVAL;

	return 0;
}

V
Vivien Didelot 已提交
785
static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd)
786
{
V
Vivien Didelot 已提交
787
	ds->cd = cd;
788

V
Vivien Didelot 已提交
789 790 791 792 793 794 795
	/* We don't support interconnected switches nor multiple trees via
	 * platform data, so this is the unique switch of the tree.
	 */
	ds->index = 0;
	ds->dst = dsa_tree_touch(0);
	if (!ds->dst)
		return -ENOMEM;
796

V
Vivien Didelot 已提交
797
	return dsa_switch_parse_ports(ds, cd);
798 799
}

800 801 802 803 804 805 806
static int dsa_switch_add(struct dsa_switch *ds)
{
	struct dsa_switch_tree *dst = ds->dst;

	return dsa_tree_add_switch(dst, ds);
}

807
static int dsa_switch_probe(struct dsa_switch *ds)
808
{
809 810
	struct dsa_chip_data *pdata = ds->dev->platform_data;
	struct device_node *np = ds->dev->of_node;
V
Vivien Didelot 已提交
811
	int err;
812

V
Vivien Didelot 已提交
813 814 815 816 817 818
	if (np)
		err = dsa_switch_parse_of(ds, np);
	else if (pdata)
		err = dsa_switch_parse(ds, pdata);
	else
		err = -ENODEV;
819

V
Vivien Didelot 已提交
820 821
	if (err)
		return err;
822

823
	return dsa_switch_add(ds);
824 825
}

826 827 828
struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n)
{
	struct dsa_switch *ds;
829
	int i;
830

831
	ds = devm_kzalloc(dev, struct_size(ds, ports, n), GFP_KERNEL);
832 833 834
	if (!ds)
		return NULL;

S
Salvatore Mesoraca 已提交
835 836 837 838 839 840 841 842 843 844 845 846 847 848
	/* We avoid allocating memory outside dsa_switch
	 * if it is not needed.
	 */
	if (n <= sizeof(ds->_bitmap) * 8) {
		ds->bitmap = &ds->_bitmap;
	} else {
		ds->bitmap = devm_kcalloc(dev,
					  BITS_TO_LONGS(n),
					  sizeof(unsigned long),
					  GFP_KERNEL);
		if (unlikely(!ds->bitmap))
			return NULL;
	}

849 850 851
	ds->dev = dev;
	ds->num_ports = n;

852 853 854 855 856
	for (i = 0; i < ds->num_ports; ++i) {
		ds->ports[i].index = i;
		ds->ports[i].ds = ds;
	}

857 858 859 860
	return ds;
}
EXPORT_SYMBOL_GPL(dsa_switch_alloc);

861
int dsa_register_switch(struct dsa_switch *ds)
862 863 864 865
{
	int err;

	mutex_lock(&dsa2_mutex);
866
	err = dsa_switch_probe(ds);
867
	dsa_tree_put(ds->dst);
868 869 870 871 872 873
	mutex_unlock(&dsa2_mutex);

	return err;
}
EXPORT_SYMBOL_GPL(dsa_register_switch);

874
static void dsa_switch_remove(struct dsa_switch *ds)
875 876
{
	struct dsa_switch_tree *dst = ds->dst;
877
	unsigned int index = ds->index;
878

879
	dsa_tree_remove_switch(dst, index);
880 881 882 883 884
}

void dsa_unregister_switch(struct dsa_switch *ds)
{
	mutex_lock(&dsa2_mutex);
885
	dsa_switch_remove(ds);
886 887 888
	mutex_unlock(&dsa2_mutex);
}
EXPORT_SYMBOL_GPL(dsa_unregister_switch);