dsa2.c 26.6 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 21
#include "dsa_priv.h"

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

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
/**
 * dsa_lag_map() - Map LAG netdev to a linear LAG ID
 * @dst: Tree in which to record the mapping.
 * @lag: Netdev that is to be mapped to an ID.
 *
 * dsa_lag_id/dsa_lag_dev can then be used to translate between the
 * two spaces. The size of the mapping space is determined by the
 * driver by setting ds->num_lag_ids. It is perfectly legal to leave
 * it unset if it is not needed, in which case these functions become
 * no-ops.
 */
void dsa_lag_map(struct dsa_switch_tree *dst, struct net_device *lag)
{
	unsigned int id;

	if (dsa_lag_id(dst, lag) >= 0)
		/* Already mapped */
		return;

	for (id = 0; id < dst->lags_len; id++) {
		if (!dsa_lag_dev(dst, id)) {
			dst->lags[id] = lag;
			return;
		}
	}

	/* No IDs left, which is OK. Some drivers do not need it. The
	 * ones that do, e.g. mv88e6xxx, will discover that dsa_lag_id
	 * returns an error for this device when joining the LAG. The
	 * driver can then return -EOPNOTSUPP back to DSA, which will
	 * fall back to a software LAG.
	 */
}

/**
 * dsa_lag_unmap() - Remove a LAG ID mapping
 * @dst: Tree in which the mapping is recorded.
 * @lag: Netdev that was mapped.
 *
 * As there may be multiple users of the mapping, it is only removed
 * if there are no other references to it.
 */
void dsa_lag_unmap(struct dsa_switch_tree *dst, struct net_device *lag)
{
	struct dsa_port *dp;
	unsigned int id;

	dsa_lag_foreach_port(dp, dst, lag)
		/* There are remaining users of this mapping */
		return;

	dsa_lags_foreach_id(id, dst) {
		if (dsa_lag_dev(dst, id) == lag) {
			dst->lags[id] = NULL;
			break;
		}
	}
}

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
struct dsa_switch *dsa_switch_find(int tree_index, int sw_index)
{
	struct dsa_switch_tree *dst;
	struct dsa_port *dp;

	list_for_each_entry(dst, &dsa_tree_list, list) {
		if (dst->index != tree_index)
			continue;

		list_for_each_entry(dp, &dst->ports, list) {
			if (dp->ds->index != sw_index)
				continue;

			return dp->ds;
		}
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(dsa_switch_find);

104
static struct dsa_switch_tree *dsa_tree_find(int index)
105 106 107
{
	struct dsa_switch_tree *dst;

108
	list_for_each_entry(dst, &dsa_tree_list, list)
109
		if (dst->index == index)
110
			return dst;
111

112 113 114
	return NULL;
}

115
static struct dsa_switch_tree *dsa_tree_alloc(int index)
116 117 118 119 120 121
{
	struct dsa_switch_tree *dst;

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

123
	dst->index = index;
124

125 126
	INIT_LIST_HEAD(&dst->rtable);

127 128
	INIT_LIST_HEAD(&dst->ports);

129
	INIT_LIST_HEAD(&dst->list);
V
Vivien Didelot 已提交
130
	list_add_tail(&dst->list, &dsa_tree_list);
131

132 133 134 135 136
	kref_init(&dst->refcount);

	return dst;
}

137 138 139 140 141 142
static void dsa_tree_free(struct dsa_switch_tree *dst)
{
	list_del(&dst->list);
	kfree(dst);
}

143
static struct dsa_switch_tree *dsa_tree_get(struct dsa_switch_tree *dst)
144
{
145 146
	if (dst)
		kref_get(&dst->refcount);
147 148 149 150

	return dst;
}

151
static struct dsa_switch_tree *dsa_tree_touch(int index)
152
{
153 154 155 156 157 158 159
	struct dsa_switch_tree *dst;

	dst = dsa_tree_find(index);
	if (dst)
		return dsa_tree_get(dst);
	else
		return dsa_tree_alloc(index);
160 161 162 163 164 165 166 167 168 169 170 171 172
}

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)
{
173 174
	if (dst)
		kref_put(&dst->refcount, dsa_tree_release);
175 176
}

177
static bool dsa_port_is_dsa(struct dsa_port *port)
178
{
179
	return port->type == DSA_PORT_TYPE_DSA;
180 181 182 183
}

static bool dsa_port_is_cpu(struct dsa_port *port)
{
184
	return port->type == DSA_PORT_TYPE_CPU;
185 186
}

187 188 189 190 191
static bool dsa_port_is_user(struct dsa_port *dp)
{
	return dp->type == DSA_PORT_TYPE_USER;
}

192 193
static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst,
						   struct device_node *dn)
194
{
195
	struct dsa_port *dp;
196

197 198 199
	list_for_each_entry(dp, &dst->ports, list)
		if (dp->dn == dn)
			return dp;
200 201 202 203

	return NULL;
}

204 205
static struct dsa_link *dsa_link_touch(struct dsa_port *dp,
				       struct dsa_port *link_dp)
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
{
	struct dsa_switch *ds = dp->ds;
	struct dsa_switch_tree *dst;
	struct dsa_link *dl;

	dst = ds->dst;

	list_for_each_entry(dl, &dst->rtable, list)
		if (dl->dp == dp && dl->link_dp == link_dp)
			return dl;

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

	dl->dp = dp;
	dl->link_dp = link_dp;

	INIT_LIST_HEAD(&dl->list);
	list_add_tail(&dl->list, &dst->rtable);

	return dl;
}

V
Vivien Didelot 已提交
230
static bool dsa_port_setup_routing_table(struct dsa_port *dp)
231
{
V
Vivien Didelot 已提交
232 233 234
	struct dsa_switch *ds = dp->ds;
	struct dsa_switch_tree *dst = ds->dst;
	struct device_node *dn = dp->dn;
V
Vivien Didelot 已提交
235
	struct of_phandle_iterator it;
236
	struct dsa_port *link_dp;
237
	struct dsa_link *dl;
V
Vivien Didelot 已提交
238
	int err;
239

V
Vivien Didelot 已提交
240 241 242 243
	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 已提交
244
			return false;
V
Vivien Didelot 已提交
245
		}
246

247 248 249 250 251
		dl = dsa_link_touch(dp, link_dp);
		if (!dl) {
			of_node_put(it.node);
			return false;
		}
252 253
	}

V
Vivien Didelot 已提交
254
	return true;
255 256
}

257
static bool dsa_tree_setup_routing_table(struct dsa_switch_tree *dst)
258
{
V
Vivien Didelot 已提交
259 260
	bool complete = true;
	struct dsa_port *dp;
261

262
	list_for_each_entry(dp, &dst->ports, list) {
263
		if (dsa_port_is_dsa(dp)) {
V
Vivien Didelot 已提交
264 265 266 267
			complete = dsa_port_setup_routing_table(dp);
			if (!complete)
				break;
		}
268 269
	}

V
Vivien Didelot 已提交
270
	return complete;
271 272
}

273 274 275 276
static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst)
{
	struct dsa_port *dp;

277 278 279
	list_for_each_entry(dp, &dst->ports, list)
		if (dsa_port_is_cpu(dp))
			return dp;
280 281 282 283 284 285

	return NULL;
}

static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst)
{
286
	struct dsa_port *cpu_dp, *dp;
287

288 289 290
	cpu_dp = dsa_tree_find_first_cpu(dst);
	if (!cpu_dp) {
		pr_err("DSA: tree %d has no CPU port\n", dst->index);
291 292 293 294
		return -EINVAL;
	}

	/* Assign the default CPU port to all ports of the fabric */
295 296 297
	list_for_each_entry(dp, &dst->ports, list)
		if (dsa_port_is_user(dp) || dsa_port_is_dsa(dp))
			dp->cpu_dp = cpu_dp;
298 299 300 301 302 303

	return 0;
}

static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst)
{
304 305 306 307 308
	struct dsa_port *dp;

	list_for_each_entry(dp, &dst->ports, list)
		if (dsa_port_is_user(dp) || dsa_port_is_dsa(dp))
			dp->cpu_dp = NULL;
309 310
}

311
static int dsa_port_setup(struct dsa_port *dp)
312
{
313
	struct devlink_port *dlp = &dp->devlink_port;
314 315 316
	bool dsa_port_link_registered = false;
	bool dsa_port_enabled = false;
	int err = 0;
317

318 319 320
	if (dp->setup)
		return 0;

321 322
	switch (dp->type) {
	case DSA_PORT_TYPE_UNUSED:
323
		dsa_port_disable(dp);
324 325
		break;
	case DSA_PORT_TYPE_CPU:
326
		err = dsa_port_link_register_of(dp);
327
		if (err)
328 329
			break;
		dsa_port_link_registered = true;
330 331

		err = dsa_port_enable(dp, NULL);
332
		if (err)
333 334 335
			break;
		dsa_port_enabled = true;

336
		break;
337
	case DSA_PORT_TYPE_DSA:
338
		err = dsa_port_link_register_of(dp);
339
		if (err)
340 341
			break;
		dsa_port_link_registered = true;
342 343

		err = dsa_port_enable(dp, NULL);
344
		if (err)
345 346 347
			break;
		dsa_port_enabled = true;

348 349
		break;
	case DSA_PORT_TYPE_USER:
350
		dp->mac = of_get_mac_address(dp->dn);
351 352
		err = dsa_slave_create(dp);
		if (err)
353
			break;
354 355

		devlink_port_type_eth_set(dlp, dp->slave);
356
		break;
357 358
	}

359 360 361 362
	if (err && dsa_port_enabled)
		dsa_port_disable(dp);
	if (err && dsa_port_link_registered)
		dsa_port_link_unregister_of(dp);
363 364
	if (err)
		return err;
365

366 367 368
	dp->setup = true;

	return 0;
369 370
}

371
static int dsa_port_devlink_setup(struct dsa_port *dp)
372
{
373
	struct devlink_port *dlp = &dp->devlink_port;
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
	struct dsa_switch_tree *dst = dp->ds->dst;
	struct devlink_port_attrs attrs = {};
	struct devlink *dl = dp->ds->devlink;
	const unsigned char *id;
	unsigned char len;
	int err;

	id = (const unsigned char *)&dst->index;
	len = sizeof(dst->index);

	attrs.phys.port_number = dp->index;
	memcpy(attrs.switch_id.id, id, len);
	attrs.switch_id.id_len = len;
	memset(dlp, 0, sizeof(*dlp));

	switch (dp->type) {
	case DSA_PORT_TYPE_UNUSED:
		attrs.flavour = DEVLINK_PORT_FLAVOUR_UNUSED;
		break;
	case DSA_PORT_TYPE_CPU:
		attrs.flavour = DEVLINK_PORT_FLAVOUR_CPU;
		break;
	case DSA_PORT_TYPE_DSA:
		attrs.flavour = DEVLINK_PORT_FLAVOUR_DSA;
		break;
	case DSA_PORT_TYPE_USER:
		attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
		break;
	}

	devlink_port_attrs_set(dlp, &attrs);
	err = devlink_port_register(dl, dlp, dp->index);

	if (!err)
		dp->devlink_port_setup = true;
409

410 411 412 413 414
	return err;
}

static void dsa_port_teardown(struct dsa_port *dp)
{
415 416
	struct devlink_port *dlp = &dp->devlink_port;

417 418 419
	if (!dp->setup)
		return;

420 421
	devlink_port_type_clear(dlp);

422 423 424 425
	switch (dp->type) {
	case DSA_PORT_TYPE_UNUSED:
		break;
	case DSA_PORT_TYPE_CPU:
426
		dsa_port_disable(dp);
427
		dsa_tag_driver_put(dp->tag_ops);
428 429
		dsa_port_link_unregister_of(dp);
		break;
430
	case DSA_PORT_TYPE_DSA:
431
		dsa_port_disable(dp);
432
		dsa_port_link_unregister_of(dp);
433 434 435 436 437 438 439
		break;
	case DSA_PORT_TYPE_USER:
		if (dp->slave) {
			dsa_slave_destroy(dp->slave);
			dp->slave = NULL;
		}
		break;
440
	}
441 442

	dp->setup = false;
443 444
}

445 446 447 448 449 450 451 452 453
static void dsa_port_devlink_teardown(struct dsa_port *dp)
{
	struct devlink_port *dlp = &dp->devlink_port;

	if (dp->devlink_port_setup)
		devlink_port_unregister(dlp);
	dp->devlink_port_setup = false;
}

A
Andrew Lunn 已提交
454 455 456 457 458 459 460 461 462 463 464 465
static int dsa_devlink_info_get(struct devlink *dl,
				struct devlink_info_req *req,
				struct netlink_ext_ack *extack)
{
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);

	if (ds->ops->devlink_info_get)
		return ds->ops->devlink_info_get(ds, req, extack);

	return -EOPNOTSUPP;
}

466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
static int dsa_devlink_sb_pool_get(struct devlink *dl,
				   unsigned int sb_index, u16 pool_index,
				   struct devlink_sb_pool_info *pool_info)
{
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);

	if (!ds->ops->devlink_sb_pool_get)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_pool_get(ds, sb_index, pool_index,
					    pool_info);
}

static int dsa_devlink_sb_pool_set(struct devlink *dl, unsigned int sb_index,
				   u16 pool_index, u32 size,
				   enum devlink_sb_threshold_type threshold_type,
				   struct netlink_ext_ack *extack)
{
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);

	if (!ds->ops->devlink_sb_pool_set)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_pool_set(ds, sb_index, pool_index, size,
					    threshold_type, extack);
}

static int dsa_devlink_sb_port_pool_get(struct devlink_port *dlp,
					unsigned int sb_index, u16 pool_index,
					u32 *p_threshold)
{
	struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
	int port = dsa_devlink_port_to_port(dlp);

	if (!ds->ops->devlink_sb_port_pool_get)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_port_pool_get(ds, port, sb_index,
						 pool_index, p_threshold);
}

static int dsa_devlink_sb_port_pool_set(struct devlink_port *dlp,
					unsigned int sb_index, u16 pool_index,
					u32 threshold,
					struct netlink_ext_ack *extack)
{
	struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
	int port = dsa_devlink_port_to_port(dlp);

	if (!ds->ops->devlink_sb_port_pool_set)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_port_pool_set(ds, port, sb_index,
						 pool_index, threshold, extack);
}

static int
dsa_devlink_sb_tc_pool_bind_get(struct devlink_port *dlp,
				unsigned int sb_index, u16 tc_index,
				enum devlink_sb_pool_type pool_type,
				u16 *p_pool_index, u32 *p_threshold)
{
	struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
	int port = dsa_devlink_port_to_port(dlp);

	if (!ds->ops->devlink_sb_tc_pool_bind_get)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_tc_pool_bind_get(ds, port, sb_index,
						    tc_index, pool_type,
						    p_pool_index, p_threshold);
}

static int
dsa_devlink_sb_tc_pool_bind_set(struct devlink_port *dlp,
				unsigned int sb_index, u16 tc_index,
				enum devlink_sb_pool_type pool_type,
				u16 pool_index, u32 threshold,
				struct netlink_ext_ack *extack)
{
	struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
	int port = dsa_devlink_port_to_port(dlp);

	if (!ds->ops->devlink_sb_tc_pool_bind_set)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_tc_pool_bind_set(ds, port, sb_index,
						    tc_index, pool_type,
						    pool_index, threshold,
						    extack);
}

static int dsa_devlink_sb_occ_snapshot(struct devlink *dl,
				       unsigned int sb_index)
{
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);

	if (!ds->ops->devlink_sb_occ_snapshot)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_occ_snapshot(ds, sb_index);
}

static int dsa_devlink_sb_occ_max_clear(struct devlink *dl,
					unsigned int sb_index)
{
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);

	if (!ds->ops->devlink_sb_occ_max_clear)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_occ_max_clear(ds, sb_index);
}

static int dsa_devlink_sb_occ_port_pool_get(struct devlink_port *dlp,
					    unsigned int sb_index,
					    u16 pool_index, u32 *p_cur,
					    u32 *p_max)
{
	struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
	int port = dsa_devlink_port_to_port(dlp);

	if (!ds->ops->devlink_sb_occ_port_pool_get)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_occ_port_pool_get(ds, port, sb_index,
						     pool_index, p_cur, p_max);
}

static int
dsa_devlink_sb_occ_tc_port_bind_get(struct devlink_port *dlp,
				    unsigned int sb_index, u16 tc_index,
				    enum devlink_sb_pool_type pool_type,
				    u32 *p_cur, u32 *p_max)
{
	struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
	int port = dsa_devlink_port_to_port(dlp);

	if (!ds->ops->devlink_sb_occ_tc_port_bind_get)
		return -EOPNOTSUPP;

	return ds->ops->devlink_sb_occ_tc_port_bind_get(ds, port,
							sb_index, tc_index,
							pool_type, p_cur,
							p_max);
}

A
Andrew Lunn 已提交
613
static const struct devlink_ops dsa_devlink_ops = {
614 615 616 617 618 619 620 621 622 623 624
	.info_get			= dsa_devlink_info_get,
	.sb_pool_get			= dsa_devlink_sb_pool_get,
	.sb_pool_set			= dsa_devlink_sb_pool_set,
	.sb_port_pool_get		= dsa_devlink_sb_port_pool_get,
	.sb_port_pool_set		= dsa_devlink_sb_port_pool_set,
	.sb_tc_pool_bind_get		= dsa_devlink_sb_tc_pool_bind_get,
	.sb_tc_pool_bind_set		= dsa_devlink_sb_tc_pool_bind_set,
	.sb_occ_snapshot		= dsa_devlink_sb_occ_snapshot,
	.sb_occ_max_clear		= dsa_devlink_sb_occ_max_clear,
	.sb_occ_port_pool_get		= dsa_devlink_sb_occ_port_pool_get,
	.sb_occ_tc_port_bind_get	= dsa_devlink_sb_occ_tc_port_bind_get,
A
Andrew Lunn 已提交
625 626
};

627
static int dsa_switch_setup(struct dsa_switch *ds)
628
{
629
	struct dsa_devlink_priv *dl_priv;
630
	struct dsa_port *dp;
631 632 633 634
	int err;

	if (ds->setup)
		return 0;
635

636
	/* Initialize ds->phys_mii_mask before registering the slave MDIO bus
637
	 * driver and before ops->setup() has run, since the switch drivers and
638 639 640
	 * the slave MDIO bus driver rely on these values for probing PHY
	 * devices or not
	 */
641
	ds->phys_mii_mask |= dsa_user_ports(ds);
642

643 644 645
	/* Add the switch to devlink before calling setup, so that setup can
	 * add dpipe tables
	 */
646
	ds->devlink = devlink_alloc(&dsa_devlink_ops, sizeof(*dl_priv));
647 648
	if (!ds->devlink)
		return -ENOMEM;
649 650
	dl_priv = devlink_priv(ds->devlink);
	dl_priv->ds = ds;
651 652 653

	err = devlink_register(ds->devlink, ds->dev);
	if (err)
654
		goto free_devlink;
655

656 657 658 659 660 661 662 663 664 665 666
	/* Setup devlink port instances now, so that the switch
	 * setup() can register regions etc, against the ports
	 */
	list_for_each_entry(dp, &ds->dst->ports, list) {
		if (dp->ds == ds) {
			err = dsa_port_devlink_setup(dp);
			if (err)
				goto unregister_devlink_ports;
		}
	}

V
Vivien Didelot 已提交
667 668
	err = dsa_switch_register_notifier(ds);
	if (err)
669
		goto unregister_devlink_ports;
V
Vivien Didelot 已提交
670

671 672
	ds->configure_vlan_while_not_filtering = true;

673 674
	err = ds->ops->setup(ds);
	if (err < 0)
675
		goto unregister_notifier;
676

677 678
	devlink_params_publish(ds->devlink);

679
	if (!ds->slave_mii_bus && ds->ops->phy_read) {
680
		ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
681 682 683 684
		if (!ds->slave_mii_bus) {
			err = -ENOMEM;
			goto unregister_notifier;
		}
685 686 687 688 689

		dsa_slave_mii_bus_init(ds);

		err = mdiobus_register(ds->slave_mii_bus);
		if (err < 0)
690
			goto unregister_notifier;
691 692
	}

693 694
	ds->setup = true;

695
	return 0;
696 697 698

unregister_notifier:
	dsa_switch_unregister_notifier(ds);
699 700 701 702
unregister_devlink_ports:
	list_for_each_entry(dp, &ds->dst->ports, list)
		if (dp->ds == ds)
			dsa_port_devlink_teardown(dp);
703 704 705 706 707 708
	devlink_unregister(ds->devlink);
free_devlink:
	devlink_free(ds->devlink);
	ds->devlink = NULL;

	return err;
709 710
}

711
static void dsa_switch_teardown(struct dsa_switch *ds)
712
{
713 714
	struct dsa_port *dp;

715 716 717
	if (!ds->setup)
		return;

718
	if (ds->slave_mii_bus && ds->ops->phy_read)
719
		mdiobus_unregister(ds->slave_mii_bus);
V
Vivien Didelot 已提交
720 721

	dsa_switch_unregister_notifier(ds);
722

723 724 725
	if (ds->ops->teardown)
		ds->ops->teardown(ds);

726
	if (ds->devlink) {
727 728 729
		list_for_each_entry(dp, &ds->dst->ports, list)
			if (dp->ds == ds)
				dsa_port_devlink_teardown(dp);
730 731 732 733 734
		devlink_unregister(ds->devlink);
		devlink_free(ds->devlink);
		ds->devlink = NULL;
	}

735
	ds->setup = false;
736 737
}

738 739
static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
{
740
	struct dsa_port *dp;
741
	int err;
742

743 744
	list_for_each_entry(dp, &dst->ports, list) {
		err = dsa_switch_setup(dp->ds);
745
		if (err)
746 747
			goto teardown;
	}
748

749 750 751
	list_for_each_entry(dp, &dst->ports, list) {
		err = dsa_port_setup(dp);
		if (err)
752
			continue;
753 754 755
	}

	return 0;
756

757 758 759
teardown:
	list_for_each_entry(dp, &dst->ports, list)
		dsa_port_teardown(dp);
760

761 762
	list_for_each_entry(dp, &dst->ports, list)
		dsa_switch_teardown(dp->ds);
763 764

	return err;
765 766 767 768
}

static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst)
{
769 770
	struct dsa_port *dp;

771 772
	list_for_each_entry(dp, &dst->ports, list)
		dsa_port_teardown(dp);
773

774 775
	list_for_each_entry(dp, &dst->ports, list)
		dsa_switch_teardown(dp->ds);
776 777
}

778 779
static int dsa_tree_setup_master(struct dsa_switch_tree *dst)
{
780 781
	struct dsa_port *dp;
	int err;
782

783 784 785 786 787 788 789 790 791
	list_for_each_entry(dp, &dst->ports, list) {
		if (dsa_port_is_cpu(dp)) {
			err = dsa_master_setup(dp->master, dp);
			if (err)
				return err;
		}
	}

	return 0;
792 793 794 795
}

static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
{
796
	struct dsa_port *dp;
797

798 799 800
	list_for_each_entry(dp, &dst->ports, list)
		if (dsa_port_is_cpu(dp))
			dsa_master_teardown(dp->master);
801 802
}

803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
static int dsa_tree_setup_lags(struct dsa_switch_tree *dst)
{
	unsigned int len = 0;
	struct dsa_port *dp;

	list_for_each_entry(dp, &dst->ports, list) {
		if (dp->ds->num_lag_ids > len)
			len = dp->ds->num_lag_ids;
	}

	if (!len)
		return 0;

	dst->lags = kcalloc(len, sizeof(*dst->lags), GFP_KERNEL);
	if (!dst->lags)
		return -ENOMEM;

	dst->lags_len = len;
	return 0;
}

static void dsa_tree_teardown_lags(struct dsa_switch_tree *dst)
{
	kfree(dst->lags);
}

V
Vivien Didelot 已提交
829
static int dsa_tree_setup(struct dsa_switch_tree *dst)
830
{
V
Vivien Didelot 已提交
831
	bool complete;
832 833
	int err;

V
Vivien Didelot 已提交
834 835 836 837 838 839
	if (dst->setup) {
		pr_err("DSA: tree %d already setup! Disjoint trees?\n",
		       dst->index);
		return -EEXIST;
	}

V
Vivien Didelot 已提交
840 841 842 843
	complete = dsa_tree_setup_routing_table(dst);
	if (!complete)
		return 0;

844 845 846 847
	err = dsa_tree_setup_default_cpu(dst);
	if (err)
		return err;

848 849
	err = dsa_tree_setup_switches(dst);
	if (err)
850
		goto teardown_default_cpu;
851

852
	err = dsa_tree_setup_master(dst);
853
	if (err)
854
		goto teardown_switches;
855

856 857 858 859
	err = dsa_tree_setup_lags(dst);
	if (err)
		goto teardown_master;

V
Vivien Didelot 已提交
860 861 862
	dst->setup = true;

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

	return 0;
865

866 867
teardown_master:
	dsa_tree_teardown_master(dst);
868 869 870 871 872 873
teardown_switches:
	dsa_tree_teardown_switches(dst);
teardown_default_cpu:
	dsa_tree_teardown_default_cpu(dst);

	return err;
874 875
}

V
Vivien Didelot 已提交
876
static void dsa_tree_teardown(struct dsa_switch_tree *dst)
877
{
878 879
	struct dsa_link *dl, *next;

V
Vivien Didelot 已提交
880
	if (!dst->setup)
881 882
		return;

883 884
	dsa_tree_teardown_lags(dst);

885
	dsa_tree_teardown_master(dst);
886

887
	dsa_tree_teardown_switches(dst);
888

889
	dsa_tree_teardown_default_cpu(dst);
890

891 892 893 894 895
	list_for_each_entry_safe(dl, next, &dst->rtable, list) {
		list_del(&dl->list);
		kfree(dl);
	}

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

	dst->setup = false;
899 900
}

901 902 903 904 905
static struct dsa_port *dsa_port_touch(struct dsa_switch *ds, int index)
{
	struct dsa_switch_tree *dst = ds->dst;
	struct dsa_port *dp;

V
Vivien Didelot 已提交
906 907 908 909 910 911 912
	list_for_each_entry(dp, &dst->ports, list)
		if (dp->ds == ds && dp->index == index)
			return dp;

	dp = kzalloc(sizeof(*dp), GFP_KERNEL);
	if (!dp)
		return NULL;
913 914 915 916 917 918 919 920 921 922

	dp->ds = ds;
	dp->index = index;

	INIT_LIST_HEAD(&dp->list);
	list_add_tail(&dp->list, &dst->ports);

	return dp;
}

923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
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;
}

941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp,
						  struct net_device *master)
{
	enum dsa_tag_protocol tag_protocol = DSA_TAG_PROTO_NONE;
	struct dsa_switch *mds, *ds = dp->ds;
	unsigned int mdp_upstream;
	struct dsa_port *mdp;

	/* It is possible to stack DSA switches onto one another when that
	 * happens the switch driver may want to know if its tagging protocol
	 * is going to work in such a configuration.
	 */
	if (dsa_slave_dev_check(master)) {
		mdp = dsa_slave_to_port(master);
		mds = mdp->ds;
		mdp_upstream = dsa_upstream_port(mds, mdp->index);
		tag_protocol = mds->ops->get_tag_protocol(mds, mdp_upstream,
							  DSA_TAG_PROTO_NONE);
	}

	/* If the master device is not itself a DSA slave in a disjoint DSA
	 * tree, then return immediately.
	 */
	return ds->ops->get_tag_protocol(ds, dp->index, tag_protocol);
}

967 968
static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master)
{
969 970 971 972 973
	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;

974
	tag_protocol = dsa_get_tag_protocol(dp, master);
975
	tag_ops = dsa_tag_driver_get(tag_protocol);
976
	if (IS_ERR(tag_ops)) {
977 978
		if (PTR_ERR(tag_ops) == -ENOPROTOOPT)
			return -EPROBE_DEFER;
979
		dev_warn(ds->dev, "No tagger for this switch\n");
980
		dp->master = NULL;
981 982 983
		return PTR_ERR(tag_ops);
	}

984
	dp->master = master;
985
	dp->type = DSA_PORT_TYPE_CPU;
986
	dp->filter = tag_ops->filter;
987 988 989
	dp->rcv = tag_ops->rcv;
	dp->tag_ops = tag_ops;
	dp->dst = dst;
990 991 992 993

	return 0;
}

994 995
static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
{
996
	struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0);
997
	const char *name = of_get_property(dn, "label", NULL);
998
	bool link = of_property_read_bool(dn, "link");
999

1000 1001
	dp->dn = dn;

1002
	if (ethernet) {
1003 1004 1005 1006 1007 1008
		struct net_device *master;

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

1009
		return dsa_port_parse_cpu(dp, master);
1010 1011
	}

1012 1013
	if (link)
		return dsa_port_parse_dsa(dp);
1014

1015
	return dsa_port_parse_user(dp, name);
1016 1017
}

V
Vivien Didelot 已提交
1018 1019
static int dsa_switch_parse_ports_of(struct dsa_switch *ds,
				     struct device_node *dn)
1020
{
1021
	struct device_node *ports, *port;
1022
	struct dsa_port *dp;
1023
	int err = 0;
1024
	u32 reg;
1025 1026 1027

	ports = of_get_child_by_name(dn, "ports");
	if (!ports) {
1028 1029 1030 1031 1032 1033
		/* The second possibility is "ethernet-ports" */
		ports = of_get_child_by_name(dn, "ethernet-ports");
		if (!ports) {
			dev_err(ds->dev, "no ports child node found\n");
			return -EINVAL;
		}
1034
	}
1035 1036 1037 1038

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

1041
		if (reg >= ds->num_ports) {
1042 1043
			dev_err(ds->dev, "port %pOF index %u exceeds num_ports (%zu)\n",
				port, reg, ds->num_ports);
1044 1045 1046
			err = -EINVAL;
			goto out_put_node;
		}
1047

1048
		dp = dsa_to_port(ds, reg);
1049 1050 1051

		err = dsa_port_parse_of(dp, port);
		if (err)
1052
			goto out_put_node;
1053 1054
	}

1055 1056 1057
out_put_node:
	of_node_put(ports);
	return err;
1058 1059
}

V
Vivien Didelot 已提交
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
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];

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

	return 0;
}

1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
static int dsa_switch_touch_ports(struct dsa_switch *ds)
{
	struct dsa_port *dp;
	int port;

	for (port = 0; port < ds->num_ports; port++) {
		dp = dsa_port_touch(ds, port);
		if (!dp)
			return -ENOMEM;
	}

	return 0;
}

V
Vivien Didelot 已提交
1094 1095 1096 1097 1098 1099 1100 1101
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;

1102 1103 1104 1105
	err = dsa_switch_touch_ports(ds);
	if (err)
		return err;

V
Vivien Didelot 已提交
1106 1107 1108
	return dsa_switch_parse_ports_of(ds, dn);
}

1109 1110 1111
static int dsa_port_parse(struct dsa_port *dp, const char *name,
			  struct device *dev)
{
1112
	if (!strcmp(name, "cpu")) {
1113 1114 1115 1116 1117 1118 1119 1120
		struct net_device *master;

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

		dev_put(master);

1121
		return dsa_port_parse_cpu(dp, master);
1122 1123
	}

1124 1125
	if (!strcmp(name, "dsa"))
		return dsa_port_parse_dsa(dp);
1126

1127
	return dsa_port_parse_user(dp, name);
1128 1129
}

V
Vivien Didelot 已提交
1130 1131
static int dsa_switch_parse_ports(struct dsa_switch *ds,
				  struct dsa_chip_data *cd)
1132 1133
{
	bool valid_name_found = false;
1134 1135 1136
	struct dsa_port *dp;
	struct device *dev;
	const char *name;
1137
	unsigned int i;
1138
	int err;
1139 1140

	for (i = 0; i < DSA_MAX_PORTS; i++) {
1141 1142
		name = cd->port_names[i];
		dev = cd->netdev[i];
1143
		dp = dsa_to_port(ds, i);
1144 1145

		if (!name)
1146 1147
			continue;

1148 1149 1150 1151
		err = dsa_port_parse(dp, name, dev);
		if (err)
			return err;

1152 1153 1154 1155 1156 1157 1158 1159 1160
		valid_name_found = true;
	}

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

	return 0;
}

V
Vivien Didelot 已提交
1161
static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd)
1162
{
1163 1164
	int err;

V
Vivien Didelot 已提交
1165
	ds->cd = cd;
1166

V
Vivien Didelot 已提交
1167 1168 1169 1170 1171 1172 1173
	/* 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;
1174

1175 1176 1177 1178
	err = dsa_switch_touch_ports(ds);
	if (err)
		return err;

V
Vivien Didelot 已提交
1179
	return dsa_switch_parse_ports(ds, cd);
1180 1181
}

1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194
static void dsa_switch_release_ports(struct dsa_switch *ds)
{
	struct dsa_switch_tree *dst = ds->dst;
	struct dsa_port *dp, *next;

	list_for_each_entry_safe(dp, next, &dst->ports, list) {
		if (dp->ds != ds)
			continue;
		list_del(&dp->list);
		kfree(dp);
	}
}

1195
static int dsa_switch_probe(struct dsa_switch *ds)
1196
{
1197
	struct dsa_switch_tree *dst;
1198 1199
	struct dsa_chip_data *pdata;
	struct device_node *np;
V
Vivien Didelot 已提交
1200
	int err;
1201

1202 1203 1204
	if (!ds->dev)
		return -ENODEV;

1205 1206 1207
	pdata = ds->dev->platform_data;
	np = ds->dev->of_node;

1208 1209 1210
	if (!ds->num_ports)
		return -EINVAL;

1211
	if (np) {
V
Vivien Didelot 已提交
1212
		err = dsa_switch_parse_of(ds, np);
1213 1214 1215
		if (err)
			dsa_switch_release_ports(ds);
	} else if (pdata) {
V
Vivien Didelot 已提交
1216
		err = dsa_switch_parse(ds, pdata);
1217 1218 1219
		if (err)
			dsa_switch_release_ports(ds);
	} else {
V
Vivien Didelot 已提交
1220
		err = -ENODEV;
1221
	}
1222

V
Vivien Didelot 已提交
1223 1224
	if (err)
		return err;
1225

1226 1227 1228
	dst = ds->dst;
	dsa_tree_get(dst);
	err = dsa_tree_setup(dst);
1229 1230
	if (err) {
		dsa_switch_release_ports(ds);
1231
		dsa_tree_put(dst);
1232
	}
1233 1234

	return err;
1235 1236
}

1237
int dsa_register_switch(struct dsa_switch *ds)
1238 1239 1240 1241
{
	int err;

	mutex_lock(&dsa2_mutex);
1242
	err = dsa_switch_probe(ds);
1243
	dsa_tree_put(ds->dst);
1244 1245 1246 1247 1248 1249
	mutex_unlock(&dsa2_mutex);

	return err;
}
EXPORT_SYMBOL_GPL(dsa_register_switch);

1250
static void dsa_switch_remove(struct dsa_switch *ds)
1251 1252
{
	struct dsa_switch_tree *dst = ds->dst;
V
Vivien Didelot 已提交
1253

1254
	dsa_tree_teardown(dst);
1255
	dsa_switch_release_ports(ds);
1256
	dsa_tree_put(dst);
1257 1258 1259 1260 1261
}

void dsa_unregister_switch(struct dsa_switch *ds)
{
	mutex_lock(&dsa2_mutex);
1262
	dsa_switch_remove(ds);
1263 1264 1265
	mutex_unlock(&dsa2_mutex);
}
EXPORT_SYMBOL_GPL(dsa_unregister_switch);