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