linux/net/dsa/legacy.c
<<
>>
Prefs
   1/*
   2 * net/dsa/legacy.c - Hardware switch handling
   3 * Copyright (c) 2008-2009 Marvell Semiconductor
   4 * Copyright (c) 2013 Florian Fainelli <florian@openwrt.org>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11
  12#include <linux/device.h>
  13#include <linux/list.h>
  14#include <linux/platform_device.h>
  15#include <linux/slab.h>
  16#include <linux/module.h>
  17#include <linux/of.h>
  18#include <linux/of_mdio.h>
  19#include <linux/of_platform.h>
  20#include <linux/of_net.h>
  21#include <linux/netdevice.h>
  22#include <linux/sysfs.h>
  23#include <linux/phy_fixed.h>
  24#include <linux/etherdevice.h>
  25
  26#include "dsa_priv.h"
  27
  28/* switch driver registration ***********************************************/
  29static DEFINE_MUTEX(dsa_switch_drivers_mutex);
  30static LIST_HEAD(dsa_switch_drivers);
  31
  32void register_switch_driver(struct dsa_switch_driver *drv)
  33{
  34        mutex_lock(&dsa_switch_drivers_mutex);
  35        list_add_tail(&drv->list, &dsa_switch_drivers);
  36        mutex_unlock(&dsa_switch_drivers_mutex);
  37}
  38EXPORT_SYMBOL_GPL(register_switch_driver);
  39
  40void unregister_switch_driver(struct dsa_switch_driver *drv)
  41{
  42        mutex_lock(&dsa_switch_drivers_mutex);
  43        list_del_init(&drv->list);
  44        mutex_unlock(&dsa_switch_drivers_mutex);
  45}
  46EXPORT_SYMBOL_GPL(unregister_switch_driver);
  47
  48static const struct dsa_switch_ops *
  49dsa_switch_probe(struct device *parent, struct device *host_dev, int sw_addr,
  50                 const char **_name, void **priv)
  51{
  52        const struct dsa_switch_ops *ret;
  53        struct list_head *list;
  54        const char *name;
  55
  56        ret = NULL;
  57        name = NULL;
  58
  59        mutex_lock(&dsa_switch_drivers_mutex);
  60        list_for_each(list, &dsa_switch_drivers) {
  61                const struct dsa_switch_ops *ops;
  62                struct dsa_switch_driver *drv;
  63
  64                drv = list_entry(list, struct dsa_switch_driver, list);
  65                ops = drv->ops;
  66
  67                name = ops->probe(parent, host_dev, sw_addr, priv);
  68                if (name != NULL) {
  69                        ret = ops;
  70                        break;
  71                }
  72        }
  73        mutex_unlock(&dsa_switch_drivers_mutex);
  74
  75        *_name = name;
  76
  77        return ret;
  78}
  79
  80/* basic switch operations **************************************************/
  81static int dsa_cpu_dsa_setups(struct dsa_switch *ds)
  82{
  83        int ret, port;
  84
  85        for (port = 0; port < ds->num_ports; port++) {
  86                if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
  87                        continue;
  88
  89                ret = dsa_port_link_register_of(&ds->ports[port]);
  90                if (ret)
  91                        return ret;
  92        }
  93        return 0;
  94}
  95
  96static int dsa_switch_setup_one(struct dsa_switch *ds,
  97                                struct net_device *master)
  98{
  99        const struct dsa_switch_ops *ops = ds->ops;
 100        struct dsa_switch_tree *dst = ds->dst;
 101        struct dsa_chip_data *cd = ds->cd;
 102        bool valid_name_found = false;
 103        int index = ds->index;
 104        struct dsa_port *dp;
 105        int i, ret;
 106
 107        /*
 108         * Validate supplied switch configuration.
 109         */
 110        for (i = 0; i < ds->num_ports; i++) {
 111                char *name;
 112
 113                dp = &ds->ports[i];
 114
 115                name = cd->port_names[i];
 116                if (name == NULL)
 117                        continue;
 118                dp->name = name;
 119
 120                if (!strcmp(name, "cpu")) {
 121                        if (dst->cpu_dp) {
 122                                netdev_err(master,
 123                                           "multiple cpu ports?!\n");
 124                                return -EINVAL;
 125                        }
 126                        dst->cpu_dp = &ds->ports[i];
 127                        dst->cpu_dp->master = master;
 128                        dp->type = DSA_PORT_TYPE_CPU;
 129                } else if (!strcmp(name, "dsa")) {
 130                        dp->type = DSA_PORT_TYPE_DSA;
 131                } else {
 132                        dp->type = DSA_PORT_TYPE_USER;
 133                }
 134                valid_name_found = true;
 135        }
 136
 137        if (!valid_name_found && i == ds->num_ports)
 138                return -EINVAL;
 139
 140        /* Make the built-in MII bus mask match the number of ports,
 141         * switch drivers can override this later
 142         */
 143        ds->phys_mii_mask |= dsa_user_ports(ds);
 144
 145        /*
 146         * If the CPU connects to this switch, set the switch tree
 147         * tagging protocol to the preferred tagging format of this
 148         * switch.
 149         */
 150        if (dst->cpu_dp->ds == ds) {
 151                const struct dsa_device_ops *tag_ops;
 152                enum dsa_tag_protocol tag_protocol;
 153
 154                tag_protocol = ops->get_tag_protocol(ds, dst->cpu_dp->index);
 155                tag_ops = dsa_resolve_tag_protocol(tag_protocol);
 156                if (IS_ERR(tag_ops))
 157                        return PTR_ERR(tag_ops);
 158
 159                dst->cpu_dp->tag_ops = tag_ops;
 160
 161                /* Few copies for faster access in master receive hot path */
 162                dst->cpu_dp->rcv = dst->cpu_dp->tag_ops->rcv;
 163                dst->cpu_dp->dst = dst;
 164        }
 165
 166        memcpy(ds->rtable, cd->rtable, sizeof(ds->rtable));
 167
 168        /*
 169         * Do basic register setup.
 170         */
 171        ret = ops->setup(ds);
 172        if (ret < 0)
 173                return ret;
 174
 175        ret = dsa_switch_register_notifier(ds);
 176        if (ret)
 177                return ret;
 178
 179        if (!ds->slave_mii_bus && ops->phy_read) {
 180                ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
 181                if (!ds->slave_mii_bus)
 182                        return -ENOMEM;
 183                dsa_slave_mii_bus_init(ds);
 184
 185                ret = mdiobus_register(ds->slave_mii_bus);
 186                if (ret < 0)
 187                        return ret;
 188        }
 189
 190        /*
 191         * Create network devices for physical switch ports.
 192         */
 193        for (i = 0; i < ds->num_ports; i++) {
 194                ds->ports[i].dn = cd->port_dn[i];
 195                ds->ports[i].cpu_dp = dst->cpu_dp;
 196
 197                if (!dsa_is_user_port(ds, i))
 198                        continue;
 199
 200                ret = dsa_slave_create(&ds->ports[i]);
 201                if (ret < 0)
 202                        netdev_err(master, "[%d]: can't create dsa slave device for port %d(%s): %d\n",
 203                                   index, i, cd->port_names[i], ret);
 204        }
 205
 206        /* Perform configuration of the CPU and DSA ports */
 207        ret = dsa_cpu_dsa_setups(ds);
 208        if (ret < 0)
 209                netdev_err(master, "[%d] : can't configure CPU and DSA ports\n",
 210                           index);
 211
 212        return 0;
 213}
 214
 215static struct dsa_switch *
 216dsa_switch_setup(struct dsa_switch_tree *dst, struct net_device *master,
 217                 int index, struct device *parent, struct device *host_dev)
 218{
 219        struct dsa_chip_data *cd = dst->pd->chip + index;
 220        const struct dsa_switch_ops *ops;
 221        struct dsa_switch *ds;
 222        int ret;
 223        const char *name;
 224        void *priv;
 225
 226        /*
 227         * Probe for switch model.
 228         */
 229        ops = dsa_switch_probe(parent, host_dev, cd->sw_addr, &name, &priv);
 230        if (!ops) {
 231                netdev_err(master, "[%d]: could not detect attached switch\n",
 232                           index);
 233                return ERR_PTR(-EINVAL);
 234        }
 235        netdev_info(master, "[%d]: detected a %s switch\n",
 236                    index, name);
 237
 238
 239        /*
 240         * Allocate and initialise switch state.
 241         */
 242        ds = dsa_switch_alloc(parent, DSA_MAX_PORTS);
 243        if (!ds)
 244                return ERR_PTR(-ENOMEM);
 245
 246        ds->dst = dst;
 247        ds->index = index;
 248        ds->cd = cd;
 249        ds->ops = ops;
 250        ds->priv = priv;
 251
 252        ret = dsa_switch_setup_one(ds, master);
 253        if (ret)
 254                return ERR_PTR(ret);
 255
 256        return ds;
 257}
 258
 259static void dsa_switch_destroy(struct dsa_switch *ds)
 260{
 261        int port;
 262
 263        /* Destroy network devices for physical switch ports. */
 264        for (port = 0; port < ds->num_ports; port++) {
 265                if (!dsa_is_user_port(ds, port))
 266                        continue;
 267
 268                if (!ds->ports[port].slave)
 269                        continue;
 270
 271                dsa_slave_destroy(ds->ports[port].slave);
 272        }
 273
 274        /* Disable configuration of the CPU and DSA ports */
 275        for (port = 0; port < ds->num_ports; port++) {
 276                if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
 277                        continue;
 278                dsa_port_link_unregister_of(&ds->ports[port]);
 279        }
 280
 281        if (ds->slave_mii_bus && ds->ops->phy_read)
 282                mdiobus_unregister(ds->slave_mii_bus);
 283
 284        dsa_switch_unregister_notifier(ds);
 285}
 286
 287/* platform driver init and cleanup *****************************************/
 288static int dev_is_class(struct device *dev, void *class)
 289{
 290        if (dev->class != NULL && !strcmp(dev->class->name, class))
 291                return 1;
 292
 293        return 0;
 294}
 295
 296static struct device *dev_find_class(struct device *parent, char *class)
 297{
 298        if (dev_is_class(parent, class)) {
 299                get_device(parent);
 300                return parent;
 301        }
 302
 303        return device_find_child(parent, class, dev_is_class);
 304}
 305
 306struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev)
 307{
 308        struct device *d;
 309
 310        d = dev_find_class(dev, "mdio_bus");
 311        if (d != NULL) {
 312                struct mii_bus *bus;
 313
 314                bus = to_mii_bus(d);
 315                put_device(d);
 316
 317                return bus;
 318        }
 319
 320        return NULL;
 321}
 322EXPORT_SYMBOL_GPL(dsa_host_dev_to_mii_bus);
 323
 324#ifdef CONFIG_OF
 325static int dsa_of_setup_routing_table(struct dsa_platform_data *pd,
 326                                        struct dsa_chip_data *cd,
 327                                        int chip_index, int port_index,
 328                                        struct device_node *link)
 329{
 330        const __be32 *reg;
 331        int link_sw_addr;
 332        struct device_node *parent_sw;
 333        int len;
 334
 335        parent_sw = of_get_parent(link);
 336        if (!parent_sw)
 337                return -EINVAL;
 338
 339        reg = of_get_property(parent_sw, "reg", &len);
 340        if (!reg || (len != sizeof(*reg) * 2))
 341                return -EINVAL;
 342
 343        /*
 344         * Get the destination switch number from the second field of its 'reg'
 345         * property, i.e. for "reg = <0x19 1>" sw_addr is '1'.
 346         */
 347        link_sw_addr = be32_to_cpup(reg + 1);
 348
 349        if (link_sw_addr >= pd->nr_chips)
 350                return -EINVAL;
 351
 352        cd->rtable[link_sw_addr] = port_index;
 353
 354        return 0;
 355}
 356
 357static int dsa_of_probe_links(struct dsa_platform_data *pd,
 358                              struct dsa_chip_data *cd,
 359                              int chip_index, int port_index,
 360                              struct device_node *port,
 361                              const char *port_name)
 362{
 363        struct device_node *link;
 364        int link_index;
 365        int ret;
 366
 367        for (link_index = 0;; link_index++) {
 368                link = of_parse_phandle(port, "link", link_index);
 369                if (!link)
 370                        break;
 371
 372                if (!strcmp(port_name, "dsa") && pd->nr_chips > 1) {
 373                        ret = dsa_of_setup_routing_table(pd, cd, chip_index,
 374                                                         port_index, link);
 375                        if (ret)
 376                                return ret;
 377                }
 378        }
 379        return 0;
 380}
 381
 382static void dsa_of_free_platform_data(struct dsa_platform_data *pd)
 383{
 384        int i;
 385        int port_index;
 386
 387        for (i = 0; i < pd->nr_chips; i++) {
 388                port_index = 0;
 389                while (port_index < DSA_MAX_PORTS) {
 390                        kfree(pd->chip[i].port_names[port_index]);
 391                        port_index++;
 392                }
 393
 394                /* Drop our reference to the MDIO bus device */
 395                if (pd->chip[i].host_dev)
 396                        put_device(pd->chip[i].host_dev);
 397        }
 398        kfree(pd->chip);
 399}
 400
 401static int dsa_of_probe(struct device *dev)
 402{
 403        struct device_node *np = dev->of_node;
 404        struct device_node *child, *mdio, *ethernet, *port;
 405        struct mii_bus *mdio_bus, *mdio_bus_switch;
 406        struct net_device *ethernet_dev;
 407        struct dsa_platform_data *pd;
 408        struct dsa_chip_data *cd;
 409        const char *port_name;
 410        int chip_index, port_index;
 411        const unsigned int *sw_addr, *port_reg;
 412        u32 eeprom_len;
 413        int ret;
 414
 415        mdio = of_parse_phandle(np, "dsa,mii-bus", 0);
 416        if (!mdio)
 417                return -EINVAL;
 418
 419        mdio_bus = of_mdio_find_bus(mdio);
 420        if (!mdio_bus)
 421                return -EPROBE_DEFER;
 422
 423        ethernet = of_parse_phandle(np, "dsa,ethernet", 0);
 424        if (!ethernet) {
 425                ret = -EINVAL;
 426                goto out_put_mdio;
 427        }
 428
 429        ethernet_dev = of_find_net_device_by_node(ethernet);
 430        if (!ethernet_dev) {
 431                ret = -EPROBE_DEFER;
 432                goto out_put_mdio;
 433        }
 434
 435        pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 436        if (!pd) {
 437                ret = -ENOMEM;
 438                goto out_put_ethernet;
 439        }
 440
 441        dev->platform_data = pd;
 442        pd->of_netdev = ethernet_dev;
 443        pd->nr_chips = of_get_available_child_count(np);
 444        if (pd->nr_chips > DSA_MAX_SWITCHES)
 445                pd->nr_chips = DSA_MAX_SWITCHES;
 446
 447        pd->chip = kcalloc(pd->nr_chips, sizeof(struct dsa_chip_data),
 448                           GFP_KERNEL);
 449        if (!pd->chip) {
 450                ret = -ENOMEM;
 451                goto out_free;
 452        }
 453
 454        chip_index = -1;
 455        for_each_available_child_of_node(np, child) {
 456                int i;
 457
 458                chip_index++;
 459                cd = &pd->chip[chip_index];
 460
 461                cd->of_node = child;
 462
 463                /* Initialize the routing table */
 464                for (i = 0; i < DSA_MAX_SWITCHES; ++i)
 465                        cd->rtable[i] = DSA_RTABLE_NONE;
 466
 467                /* When assigning the host device, increment its refcount */
 468                cd->host_dev = get_device(&mdio_bus->dev);
 469
 470                sw_addr = of_get_property(child, "reg", NULL);
 471                if (!sw_addr)
 472                        continue;
 473
 474                cd->sw_addr = be32_to_cpup(sw_addr);
 475                if (cd->sw_addr >= PHY_MAX_ADDR)
 476                        continue;
 477
 478                if (!of_property_read_u32(child, "eeprom-length", &eeprom_len))
 479                        cd->eeprom_len = eeprom_len;
 480
 481                mdio = of_parse_phandle(child, "mii-bus", 0);
 482                if (mdio) {
 483                        mdio_bus_switch = of_mdio_find_bus(mdio);
 484                        if (!mdio_bus_switch) {
 485                                ret = -EPROBE_DEFER;
 486                                goto out_free_chip;
 487                        }
 488
 489                        /* Drop the mdio_bus device ref, replacing the host
 490                         * device with the mdio_bus_switch device, keeping
 491                         * the refcount from of_mdio_find_bus() above.
 492                         */
 493                        put_device(cd->host_dev);
 494                        cd->host_dev = &mdio_bus_switch->dev;
 495                }
 496
 497                for_each_available_child_of_node(child, port) {
 498                        port_reg = of_get_property(port, "reg", NULL);
 499                        if (!port_reg)
 500                                continue;
 501
 502                        port_index = be32_to_cpup(port_reg);
 503                        if (port_index >= DSA_MAX_PORTS)
 504                                break;
 505
 506                        port_name = of_get_property(port, "label", NULL);
 507                        if (!port_name)
 508                                continue;
 509
 510                        cd->port_dn[port_index] = port;
 511
 512                        cd->port_names[port_index] = kstrdup(port_name,
 513                                        GFP_KERNEL);
 514                        if (!cd->port_names[port_index]) {
 515                                ret = -ENOMEM;
 516                                goto out_free_chip;
 517                        }
 518
 519                        ret = dsa_of_probe_links(pd, cd, chip_index,
 520                                                 port_index, port, port_name);
 521                        if (ret)
 522                                goto out_free_chip;
 523
 524                }
 525        }
 526
 527        /* The individual chips hold their own refcount on the mdio bus,
 528         * so drop ours */
 529        put_device(&mdio_bus->dev);
 530
 531        return 0;
 532
 533out_free_chip:
 534        dsa_of_free_platform_data(pd);
 535out_free:
 536        kfree(pd);
 537        dev->platform_data = NULL;
 538out_put_ethernet:
 539        put_device(&ethernet_dev->dev);
 540out_put_mdio:
 541        put_device(&mdio_bus->dev);
 542        return ret;
 543}
 544
 545static void dsa_of_remove(struct device *dev)
 546{
 547        struct dsa_platform_data *pd = dev->platform_data;
 548
 549        if (!dev->of_node)
 550                return;
 551
 552        dsa_of_free_platform_data(pd);
 553        put_device(&pd->of_netdev->dev);
 554        kfree(pd);
 555}
 556#else
 557static inline int dsa_of_probe(struct device *dev)
 558{
 559        return 0;
 560}
 561
 562static inline void dsa_of_remove(struct device *dev)
 563{
 564}
 565#endif
 566
 567static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
 568                         struct device *parent, struct dsa_platform_data *pd)
 569{
 570        int i;
 571        unsigned configured = 0;
 572
 573        dst->pd = pd;
 574
 575        for (i = 0; i < pd->nr_chips; i++) {
 576                struct dsa_switch *ds;
 577
 578                ds = dsa_switch_setup(dst, dev, i, parent, pd->chip[i].host_dev);
 579                if (IS_ERR(ds)) {
 580                        netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n",
 581                                   i, PTR_ERR(ds));
 582                        continue;
 583                }
 584
 585                dst->ds[i] = ds;
 586
 587                ++configured;
 588        }
 589
 590        /*
 591         * If no switch was found, exit cleanly
 592         */
 593        if (!configured)
 594                return -EPROBE_DEFER;
 595
 596        return dsa_master_setup(dst->cpu_dp->master, dst->cpu_dp);
 597}
 598
 599static int dsa_probe(struct platform_device *pdev)
 600{
 601        struct dsa_platform_data *pd = pdev->dev.platform_data;
 602        struct net_device *dev;
 603        struct dsa_switch_tree *dst;
 604        int ret;
 605
 606        if (pdev->dev.of_node) {
 607                ret = dsa_of_probe(&pdev->dev);
 608                if (ret)
 609                        return ret;
 610
 611                pd = pdev->dev.platform_data;
 612        }
 613
 614        if (pd == NULL || (pd->netdev == NULL && pd->of_netdev == NULL))
 615                return -EINVAL;
 616
 617        if (pd->of_netdev) {
 618                dev = pd->of_netdev;
 619                dev_hold(dev);
 620        } else {
 621                dev = dsa_dev_to_net_device(pd->netdev);
 622        }
 623        if (dev == NULL) {
 624                ret = -EPROBE_DEFER;
 625                goto out;
 626        }
 627
 628        if (dev->dsa_ptr != NULL) {
 629                dev_put(dev);
 630                ret = -EEXIST;
 631                goto out;
 632        }
 633
 634        dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
 635        if (dst == NULL) {
 636                dev_put(dev);
 637                ret = -ENOMEM;
 638                goto out;
 639        }
 640
 641        platform_set_drvdata(pdev, dst);
 642
 643        ret = dsa_setup_dst(dst, dev, &pdev->dev, pd);
 644        if (ret) {
 645                dev_put(dev);
 646                goto out;
 647        }
 648
 649        return 0;
 650
 651out:
 652        dsa_of_remove(&pdev->dev);
 653
 654        return ret;
 655}
 656
 657static void dsa_remove_dst(struct dsa_switch_tree *dst)
 658{
 659        int i;
 660
 661        dsa_master_teardown(dst->cpu_dp->master);
 662
 663        for (i = 0; i < dst->pd->nr_chips; i++) {
 664                struct dsa_switch *ds = dst->ds[i];
 665
 666                if (ds)
 667                        dsa_switch_destroy(ds);
 668        }
 669
 670        dev_put(dst->cpu_dp->master);
 671}
 672
 673static int dsa_remove(struct platform_device *pdev)
 674{
 675        struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
 676
 677        dsa_remove_dst(dst);
 678        dsa_of_remove(&pdev->dev);
 679
 680        return 0;
 681}
 682
 683static void dsa_shutdown(struct platform_device *pdev)
 684{
 685}
 686
 687#ifdef CONFIG_PM_SLEEP
 688static int dsa_suspend(struct device *d)
 689{
 690        struct platform_device *pdev = to_platform_device(d);
 691        struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
 692        int i, ret = 0;
 693
 694        for (i = 0; i < dst->pd->nr_chips; i++) {
 695                struct dsa_switch *ds = dst->ds[i];
 696
 697                if (ds != NULL)
 698                        ret = dsa_switch_suspend(ds);
 699        }
 700
 701        return ret;
 702}
 703
 704static int dsa_resume(struct device *d)
 705{
 706        struct platform_device *pdev = to_platform_device(d);
 707        struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
 708        int i, ret = 0;
 709
 710        for (i = 0; i < dst->pd->nr_chips; i++) {
 711                struct dsa_switch *ds = dst->ds[i];
 712
 713                if (ds != NULL)
 714                        ret = dsa_switch_resume(ds);
 715        }
 716
 717        return ret;
 718}
 719#endif
 720
 721static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa_suspend, dsa_resume);
 722
 723static const struct of_device_id dsa_of_match_table[] = {
 724        { .compatible = "marvell,dsa", },
 725        {}
 726};
 727MODULE_DEVICE_TABLE(of, dsa_of_match_table);
 728
 729static struct platform_driver dsa_driver = {
 730        .probe          = dsa_probe,
 731        .remove         = dsa_remove,
 732        .shutdown       = dsa_shutdown,
 733        .driver = {
 734                .name   = "dsa",
 735                .of_match_table = dsa_of_match_table,
 736                .pm     = &dsa_pm_ops,
 737        },
 738};
 739
 740int dsa_legacy_register(void)
 741{
 742        return platform_driver_register(&dsa_driver);
 743}
 744
 745void dsa_legacy_unregister(void)
 746{
 747        platform_driver_unregister(&dsa_driver);
 748}
 749