at v5.4-rc2 897 lines 18 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * net/dsa/dsa2.c - Hardware switch handling, binding version 2 4 * Copyright (c) 2008-2009 Marvell Semiconductor 5 * Copyright (c) 2013 Florian Fainelli <florian@openwrt.org> 6 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch> 7 */ 8 9#include <linux/device.h> 10#include <linux/err.h> 11#include <linux/list.h> 12#include <linux/netdevice.h> 13#include <linux/slab.h> 14#include <linux/rtnetlink.h> 15#include <linux/of.h> 16#include <linux/of_net.h> 17#include <net/devlink.h> 18 19#include "dsa_priv.h" 20 21static LIST_HEAD(dsa_tree_list); 22static DEFINE_MUTEX(dsa2_mutex); 23 24static const struct devlink_ops dsa_devlink_ops = { 25}; 26 27static struct dsa_switch_tree *dsa_tree_find(int index) 28{ 29 struct dsa_switch_tree *dst; 30 31 list_for_each_entry(dst, &dsa_tree_list, list) 32 if (dst->index == index) 33 return dst; 34 35 return NULL; 36} 37 38static struct dsa_switch_tree *dsa_tree_alloc(int index) 39{ 40 struct dsa_switch_tree *dst; 41 42 dst = kzalloc(sizeof(*dst), GFP_KERNEL); 43 if (!dst) 44 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 kref_init(&dst->refcount); 52 53 return dst; 54} 55 56static void dsa_tree_free(struct dsa_switch_tree *dst) 57{ 58 list_del(&dst->list); 59 kfree(dst); 60} 61 62static struct dsa_switch_tree *dsa_tree_get(struct dsa_switch_tree *dst) 63{ 64 if (dst) 65 kref_get(&dst->refcount); 66 67 return dst; 68} 69 70static struct dsa_switch_tree *dsa_tree_touch(int index) 71{ 72 struct dsa_switch_tree *dst; 73 74 dst = dsa_tree_find(index); 75 if (dst) 76 return dsa_tree_get(dst); 77 else 78 return dsa_tree_alloc(index); 79} 80 81static void dsa_tree_release(struct kref *ref) 82{ 83 struct dsa_switch_tree *dst; 84 85 dst = container_of(ref, struct dsa_switch_tree, refcount); 86 87 dsa_tree_free(dst); 88} 89 90static void dsa_tree_put(struct dsa_switch_tree *dst) 91{ 92 if (dst) 93 kref_put(&dst->refcount, dsa_tree_release); 94} 95 96static bool dsa_port_is_dsa(struct dsa_port *port) 97{ 98 return port->type == DSA_PORT_TYPE_DSA; 99} 100 101static bool dsa_port_is_cpu(struct dsa_port *port) 102{ 103 return port->type == DSA_PORT_TYPE_CPU; 104} 105 106static bool dsa_port_is_user(struct dsa_port *dp) 107{ 108 return dp->type == DSA_PORT_TYPE_USER; 109} 110 111static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst, 112 struct device_node *dn) 113{ 114 struct dsa_switch *ds; 115 struct dsa_port *dp; 116 int device, port; 117 118 for (device = 0; device < DSA_MAX_SWITCHES; device++) { 119 ds = dst->ds[device]; 120 if (!ds) 121 continue; 122 123 for (port = 0; port < ds->num_ports; port++) { 124 dp = &ds->ports[port]; 125 126 if (dp->dn == dn) 127 return dp; 128 } 129 } 130 131 return NULL; 132} 133 134static bool dsa_port_setup_routing_table(struct dsa_port *dp) 135{ 136 struct dsa_switch *ds = dp->ds; 137 struct dsa_switch_tree *dst = ds->dst; 138 struct device_node *dn = dp->dn; 139 struct of_phandle_iterator it; 140 struct dsa_port *link_dp; 141 int err; 142 143 of_for_each_phandle(&it, err, dn, "link", NULL, 0) { 144 link_dp = dsa_tree_find_port_by_node(dst, it.node); 145 if (!link_dp) { 146 of_node_put(it.node); 147 return false; 148 } 149 150 ds->rtable[link_dp->ds->index] = dp->index; 151 } 152 153 return true; 154} 155 156static bool dsa_switch_setup_routing_table(struct dsa_switch *ds) 157{ 158 bool complete = true; 159 struct dsa_port *dp; 160 int i; 161 162 for (i = 0; i < DSA_MAX_SWITCHES; i++) 163 ds->rtable[i] = DSA_RTABLE_NONE; 164 165 for (i = 0; i < ds->num_ports; i++) { 166 dp = &ds->ports[i]; 167 168 if (dsa_port_is_dsa(dp)) { 169 complete = dsa_port_setup_routing_table(dp); 170 if (!complete) 171 break; 172 } 173 } 174 175 return complete; 176} 177 178static bool dsa_tree_setup_routing_table(struct dsa_switch_tree *dst) 179{ 180 struct dsa_switch *ds; 181 bool complete = true; 182 int device; 183 184 for (device = 0; device < DSA_MAX_SWITCHES; device++) { 185 ds = dst->ds[device]; 186 if (!ds) 187 continue; 188 189 complete = dsa_switch_setup_routing_table(ds); 190 if (!complete) 191 break; 192 } 193 194 return complete; 195} 196 197static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst) 198{ 199 struct dsa_switch *ds; 200 struct dsa_port *dp; 201 int device, port; 202 203 for (device = 0; device < DSA_MAX_SWITCHES; device++) { 204 ds = dst->ds[device]; 205 if (!ds) 206 continue; 207 208 for (port = 0; port < ds->num_ports; port++) { 209 dp = &ds->ports[port]; 210 211 if (dsa_port_is_cpu(dp)) 212 return dp; 213 } 214 } 215 216 return NULL; 217} 218 219static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst) 220{ 221 struct dsa_switch *ds; 222 struct dsa_port *dp; 223 int device, port; 224 225 /* DSA currently only supports a single CPU port */ 226 dst->cpu_dp = dsa_tree_find_first_cpu(dst); 227 if (!dst->cpu_dp) { 228 pr_warn("Tree has no master device\n"); 229 return -EINVAL; 230 } 231 232 /* Assign the default CPU port to all ports of the fabric */ 233 for (device = 0; device < DSA_MAX_SWITCHES; device++) { 234 ds = dst->ds[device]; 235 if (!ds) 236 continue; 237 238 for (port = 0; port < ds->num_ports; port++) { 239 dp = &ds->ports[port]; 240 241 if (dsa_port_is_user(dp) || dsa_port_is_dsa(dp)) 242 dp->cpu_dp = dst->cpu_dp; 243 } 244 } 245 246 return 0; 247} 248 249static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst) 250{ 251 /* DSA currently only supports a single CPU port */ 252 dst->cpu_dp = NULL; 253} 254 255static int dsa_port_setup(struct dsa_port *dp) 256{ 257 struct dsa_switch *ds = dp->ds; 258 struct dsa_switch_tree *dst = ds->dst; 259 const unsigned char *id = (const unsigned char *)&dst->index; 260 const unsigned char len = sizeof(dst->index); 261 struct devlink_port *dlp = &dp->devlink_port; 262 bool dsa_port_link_registered = false; 263 bool devlink_port_registered = false; 264 struct devlink *dl = ds->devlink; 265 bool dsa_port_enabled = false; 266 int err = 0; 267 268 switch (dp->type) { 269 case DSA_PORT_TYPE_UNUSED: 270 dsa_port_disable(dp); 271 break; 272 case DSA_PORT_TYPE_CPU: 273 memset(dlp, 0, sizeof(*dlp)); 274 devlink_port_attrs_set(dlp, DEVLINK_PORT_FLAVOUR_CPU, 275 dp->index, false, 0, id, len); 276 err = devlink_port_register(dl, dlp, dp->index); 277 if (err) 278 break; 279 devlink_port_registered = true; 280 281 err = dsa_port_link_register_of(dp); 282 if (err) 283 break; 284 dsa_port_link_registered = true; 285 286 err = dsa_port_enable(dp, NULL); 287 if (err) 288 break; 289 dsa_port_enabled = true; 290 291 break; 292 case DSA_PORT_TYPE_DSA: 293 memset(dlp, 0, sizeof(*dlp)); 294 devlink_port_attrs_set(dlp, DEVLINK_PORT_FLAVOUR_DSA, 295 dp->index, false, 0, id, len); 296 err = devlink_port_register(dl, dlp, dp->index); 297 if (err) 298 break; 299 devlink_port_registered = true; 300 301 err = dsa_port_link_register_of(dp); 302 if (err) 303 break; 304 dsa_port_link_registered = true; 305 306 err = dsa_port_enable(dp, NULL); 307 if (err) 308 break; 309 dsa_port_enabled = true; 310 311 break; 312 case DSA_PORT_TYPE_USER: 313 memset(dlp, 0, sizeof(*dlp)); 314 devlink_port_attrs_set(dlp, DEVLINK_PORT_FLAVOUR_PHYSICAL, 315 dp->index, false, 0, id, len); 316 err = devlink_port_register(dl, dlp, dp->index); 317 if (err) 318 break; 319 devlink_port_registered = true; 320 321 dp->mac = of_get_mac_address(dp->dn); 322 err = dsa_slave_create(dp); 323 if (err) 324 break; 325 326 devlink_port_type_eth_set(dlp, dp->slave); 327 break; 328 } 329 330 if (err && dsa_port_enabled) 331 dsa_port_disable(dp); 332 if (err && dsa_port_link_registered) 333 dsa_port_link_unregister_of(dp); 334 if (err && devlink_port_registered) 335 devlink_port_unregister(dlp); 336 337 return err; 338} 339 340static void dsa_port_teardown(struct dsa_port *dp) 341{ 342 struct devlink_port *dlp = &dp->devlink_port; 343 344 switch (dp->type) { 345 case DSA_PORT_TYPE_UNUSED: 346 break; 347 case DSA_PORT_TYPE_CPU: 348 dsa_port_disable(dp); 349 dsa_tag_driver_put(dp->tag_ops); 350 devlink_port_unregister(dlp); 351 dsa_port_link_unregister_of(dp); 352 break; 353 case DSA_PORT_TYPE_DSA: 354 dsa_port_disable(dp); 355 devlink_port_unregister(dlp); 356 dsa_port_link_unregister_of(dp); 357 break; 358 case DSA_PORT_TYPE_USER: 359 devlink_port_unregister(dlp); 360 if (dp->slave) { 361 dsa_slave_destroy(dp->slave); 362 dp->slave = NULL; 363 } 364 break; 365 } 366} 367 368static int dsa_switch_setup(struct dsa_switch *ds) 369{ 370 int err = 0; 371 372 /* Initialize ds->phys_mii_mask before registering the slave MDIO bus 373 * driver and before ops->setup() has run, since the switch drivers and 374 * the slave MDIO bus driver rely on these values for probing PHY 375 * devices or not 376 */ 377 ds->phys_mii_mask |= dsa_user_ports(ds); 378 379 /* Add the switch to devlink before calling setup, so that setup can 380 * add dpipe tables 381 */ 382 ds->devlink = devlink_alloc(&dsa_devlink_ops, 0); 383 if (!ds->devlink) 384 return -ENOMEM; 385 386 err = devlink_register(ds->devlink, ds->dev); 387 if (err) 388 goto free_devlink; 389 390 err = dsa_switch_register_notifier(ds); 391 if (err) 392 goto unregister_devlink; 393 394 err = ds->ops->setup(ds); 395 if (err < 0) 396 goto unregister_notifier; 397 398 if (!ds->slave_mii_bus && ds->ops->phy_read) { 399 ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev); 400 if (!ds->slave_mii_bus) { 401 err = -ENOMEM; 402 goto unregister_notifier; 403 } 404 405 dsa_slave_mii_bus_init(ds); 406 407 err = mdiobus_register(ds->slave_mii_bus); 408 if (err < 0) 409 goto unregister_notifier; 410 } 411 412 return 0; 413 414unregister_notifier: 415 dsa_switch_unregister_notifier(ds); 416unregister_devlink: 417 devlink_unregister(ds->devlink); 418free_devlink: 419 devlink_free(ds->devlink); 420 ds->devlink = NULL; 421 422 return err; 423} 424 425static void dsa_switch_teardown(struct dsa_switch *ds) 426{ 427 if (ds->slave_mii_bus && ds->ops->phy_read) 428 mdiobus_unregister(ds->slave_mii_bus); 429 430 dsa_switch_unregister_notifier(ds); 431 432 if (ds->ops->teardown) 433 ds->ops->teardown(ds); 434 435 if (ds->devlink) { 436 devlink_unregister(ds->devlink); 437 devlink_free(ds->devlink); 438 ds->devlink = NULL; 439 } 440 441} 442 443static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) 444{ 445 struct dsa_switch *ds; 446 struct dsa_port *dp; 447 int device, port, i; 448 int err = 0; 449 450 for (device = 0; device < DSA_MAX_SWITCHES; device++) { 451 ds = dst->ds[device]; 452 if (!ds) 453 continue; 454 455 err = dsa_switch_setup(ds); 456 if (err) 457 goto switch_teardown; 458 459 for (port = 0; port < ds->num_ports; port++) { 460 dp = &ds->ports[port]; 461 462 err = dsa_port_setup(dp); 463 if (err) 464 goto ports_teardown; 465 } 466 } 467 468 return 0; 469 470ports_teardown: 471 for (i = 0; i < port; i++) 472 dsa_port_teardown(&ds->ports[i]); 473 474 dsa_switch_teardown(ds); 475 476switch_teardown: 477 for (i = 0; i < device; i++) { 478 ds = dst->ds[i]; 479 if (!ds) 480 continue; 481 482 for (port = 0; port < ds->num_ports; port++) { 483 dp = &ds->ports[port]; 484 485 dsa_port_teardown(dp); 486 } 487 488 dsa_switch_teardown(ds); 489 } 490 491 return err; 492} 493 494static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst) 495{ 496 struct dsa_switch *ds; 497 struct dsa_port *dp; 498 int device, port; 499 500 for (device = 0; device < DSA_MAX_SWITCHES; device++) { 501 ds = dst->ds[device]; 502 if (!ds) 503 continue; 504 505 for (port = 0; port < ds->num_ports; port++) { 506 dp = &ds->ports[port]; 507 508 dsa_port_teardown(dp); 509 } 510 511 dsa_switch_teardown(ds); 512 } 513} 514 515static int dsa_tree_setup_master(struct dsa_switch_tree *dst) 516{ 517 struct dsa_port *cpu_dp = dst->cpu_dp; 518 struct net_device *master = cpu_dp->master; 519 520 /* DSA currently supports a single pair of CPU port and master device */ 521 return dsa_master_setup(master, cpu_dp); 522} 523 524static void dsa_tree_teardown_master(struct dsa_switch_tree *dst) 525{ 526 struct dsa_port *cpu_dp = dst->cpu_dp; 527 struct net_device *master = cpu_dp->master; 528 529 return dsa_master_teardown(master); 530} 531 532static int dsa_tree_setup(struct dsa_switch_tree *dst) 533{ 534 bool complete; 535 int err; 536 537 if (dst->setup) { 538 pr_err("DSA: tree %d already setup! Disjoint trees?\n", 539 dst->index); 540 return -EEXIST; 541 } 542 543 complete = dsa_tree_setup_routing_table(dst); 544 if (!complete) 545 return 0; 546 547 err = dsa_tree_setup_default_cpu(dst); 548 if (err) 549 return err; 550 551 err = dsa_tree_setup_switches(dst); 552 if (err) 553 goto teardown_default_cpu; 554 555 err = dsa_tree_setup_master(dst); 556 if (err) 557 goto teardown_switches; 558 559 dst->setup = true; 560 561 pr_info("DSA: tree %d setup\n", dst->index); 562 563 return 0; 564 565teardown_switches: 566 dsa_tree_teardown_switches(dst); 567teardown_default_cpu: 568 dsa_tree_teardown_default_cpu(dst); 569 570 return err; 571} 572 573static void dsa_tree_teardown(struct dsa_switch_tree *dst) 574{ 575 if (!dst->setup) 576 return; 577 578 dsa_tree_teardown_master(dst); 579 580 dsa_tree_teardown_switches(dst); 581 582 dsa_tree_teardown_default_cpu(dst); 583 584 pr_info("DSA: tree %d torn down\n", dst->index); 585 586 dst->setup = false; 587} 588 589static void dsa_tree_remove_switch(struct dsa_switch_tree *dst, 590 unsigned int index) 591{ 592 dsa_tree_teardown(dst); 593 594 dst->ds[index] = NULL; 595 dsa_tree_put(dst); 596} 597 598static int dsa_tree_add_switch(struct dsa_switch_tree *dst, 599 struct dsa_switch *ds) 600{ 601 unsigned int index = ds->index; 602 int err; 603 604 if (dst->ds[index]) 605 return -EBUSY; 606 607 dsa_tree_get(dst); 608 dst->ds[index] = ds; 609 610 err = dsa_tree_setup(dst); 611 if (err) { 612 dst->ds[index] = NULL; 613 dsa_tree_put(dst); 614 } 615 616 return err; 617} 618 619static int dsa_port_parse_user(struct dsa_port *dp, const char *name) 620{ 621 if (!name) 622 name = "eth%d"; 623 624 dp->type = DSA_PORT_TYPE_USER; 625 dp->name = name; 626 627 return 0; 628} 629 630static int dsa_port_parse_dsa(struct dsa_port *dp) 631{ 632 dp->type = DSA_PORT_TYPE_DSA; 633 634 return 0; 635} 636 637static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) 638{ 639 struct dsa_switch *ds = dp->ds; 640 struct dsa_switch_tree *dst = ds->dst; 641 const struct dsa_device_ops *tag_ops; 642 enum dsa_tag_protocol tag_protocol; 643 644 tag_protocol = ds->ops->get_tag_protocol(ds, dp->index); 645 tag_ops = dsa_tag_driver_get(tag_protocol); 646 if (IS_ERR(tag_ops)) { 647 if (PTR_ERR(tag_ops) == -ENOPROTOOPT) 648 return -EPROBE_DEFER; 649 dev_warn(ds->dev, "No tagger for this switch\n"); 650 return PTR_ERR(tag_ops); 651 } 652 653 dp->type = DSA_PORT_TYPE_CPU; 654 dp->filter = tag_ops->filter; 655 dp->rcv = tag_ops->rcv; 656 dp->tag_ops = tag_ops; 657 dp->master = master; 658 dp->dst = dst; 659 660 return 0; 661} 662 663static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) 664{ 665 struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0); 666 const char *name = of_get_property(dn, "label", NULL); 667 bool link = of_property_read_bool(dn, "link"); 668 669 dp->dn = dn; 670 671 if (ethernet) { 672 struct net_device *master; 673 674 master = of_find_net_device_by_node(ethernet); 675 if (!master) 676 return -EPROBE_DEFER; 677 678 return dsa_port_parse_cpu(dp, master); 679 } 680 681 if (link) 682 return dsa_port_parse_dsa(dp); 683 684 return dsa_port_parse_user(dp, name); 685} 686 687static int dsa_switch_parse_ports_of(struct dsa_switch *ds, 688 struct device_node *dn) 689{ 690 struct device_node *ports, *port; 691 struct dsa_port *dp; 692 int err = 0; 693 u32 reg; 694 695 ports = of_get_child_by_name(dn, "ports"); 696 if (!ports) { 697 dev_err(ds->dev, "no ports child node found\n"); 698 return -EINVAL; 699 } 700 701 for_each_available_child_of_node(ports, port) { 702 err = of_property_read_u32(port, "reg", &reg); 703 if (err) 704 goto out_put_node; 705 706 if (reg >= ds->num_ports) { 707 err = -EINVAL; 708 goto out_put_node; 709 } 710 711 dp = &ds->ports[reg]; 712 713 err = dsa_port_parse_of(dp, port); 714 if (err) 715 goto out_put_node; 716 } 717 718out_put_node: 719 of_node_put(ports); 720 return err; 721} 722 723static int dsa_switch_parse_member_of(struct dsa_switch *ds, 724 struct device_node *dn) 725{ 726 u32 m[2] = { 0, 0 }; 727 int sz; 728 729 /* Don't error out if this optional property isn't found */ 730 sz = of_property_read_variable_u32_array(dn, "dsa,member", m, 2, 2); 731 if (sz < 0 && sz != -EINVAL) 732 return sz; 733 734 ds->index = m[1]; 735 if (ds->index >= DSA_MAX_SWITCHES) 736 return -EINVAL; 737 738 ds->dst = dsa_tree_touch(m[0]); 739 if (!ds->dst) 740 return -ENOMEM; 741 742 return 0; 743} 744 745static int dsa_switch_parse_of(struct dsa_switch *ds, struct device_node *dn) 746{ 747 int err; 748 749 err = dsa_switch_parse_member_of(ds, dn); 750 if (err) 751 return err; 752 753 return dsa_switch_parse_ports_of(ds, dn); 754} 755 756static int dsa_port_parse(struct dsa_port *dp, const char *name, 757 struct device *dev) 758{ 759 if (!strcmp(name, "cpu")) { 760 struct net_device *master; 761 762 master = dsa_dev_to_net_device(dev); 763 if (!master) 764 return -EPROBE_DEFER; 765 766 dev_put(master); 767 768 return dsa_port_parse_cpu(dp, master); 769 } 770 771 if (!strcmp(name, "dsa")) 772 return dsa_port_parse_dsa(dp); 773 774 return dsa_port_parse_user(dp, name); 775} 776 777static int dsa_switch_parse_ports(struct dsa_switch *ds, 778 struct dsa_chip_data *cd) 779{ 780 bool valid_name_found = false; 781 struct dsa_port *dp; 782 struct device *dev; 783 const char *name; 784 unsigned int i; 785 int err; 786 787 for (i = 0; i < DSA_MAX_PORTS; i++) { 788 name = cd->port_names[i]; 789 dev = cd->netdev[i]; 790 dp = &ds->ports[i]; 791 792 if (!name) 793 continue; 794 795 err = dsa_port_parse(dp, name, dev); 796 if (err) 797 return err; 798 799 valid_name_found = true; 800 } 801 802 if (!valid_name_found && i == DSA_MAX_PORTS) 803 return -EINVAL; 804 805 return 0; 806} 807 808static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd) 809{ 810 ds->cd = cd; 811 812 /* We don't support interconnected switches nor multiple trees via 813 * platform data, so this is the unique switch of the tree. 814 */ 815 ds->index = 0; 816 ds->dst = dsa_tree_touch(0); 817 if (!ds->dst) 818 return -ENOMEM; 819 820 return dsa_switch_parse_ports(ds, cd); 821} 822 823static int dsa_switch_add(struct dsa_switch *ds) 824{ 825 struct dsa_switch_tree *dst = ds->dst; 826 827 return dsa_tree_add_switch(dst, ds); 828} 829 830static int dsa_switch_probe(struct dsa_switch *ds) 831{ 832 struct dsa_chip_data *pdata = ds->dev->platform_data; 833 struct device_node *np = ds->dev->of_node; 834 int err; 835 836 if (np) 837 err = dsa_switch_parse_of(ds, np); 838 else if (pdata) 839 err = dsa_switch_parse(ds, pdata); 840 else 841 err = -ENODEV; 842 843 if (err) 844 return err; 845 846 return dsa_switch_add(ds); 847} 848 849struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n) 850{ 851 struct dsa_switch *ds; 852 int i; 853 854 ds = devm_kzalloc(dev, struct_size(ds, ports, n), GFP_KERNEL); 855 if (!ds) 856 return NULL; 857 858 ds->dev = dev; 859 ds->num_ports = n; 860 861 for (i = 0; i < ds->num_ports; ++i) { 862 ds->ports[i].index = i; 863 ds->ports[i].ds = ds; 864 } 865 866 return ds; 867} 868EXPORT_SYMBOL_GPL(dsa_switch_alloc); 869 870int dsa_register_switch(struct dsa_switch *ds) 871{ 872 int err; 873 874 mutex_lock(&dsa2_mutex); 875 err = dsa_switch_probe(ds); 876 dsa_tree_put(ds->dst); 877 mutex_unlock(&dsa2_mutex); 878 879 return err; 880} 881EXPORT_SYMBOL_GPL(dsa_register_switch); 882 883static void dsa_switch_remove(struct dsa_switch *ds) 884{ 885 struct dsa_switch_tree *dst = ds->dst; 886 unsigned int index = ds->index; 887 888 dsa_tree_remove_switch(dst, index); 889} 890 891void dsa_unregister_switch(struct dsa_switch *ds) 892{ 893 mutex_lock(&dsa2_mutex); 894 dsa_switch_remove(ds); 895 mutex_unlock(&dsa2_mutex); 896} 897EXPORT_SYMBOL_GPL(dsa_unregister_switch);