linux/net/dsa/dsa.c
<<
>>
Prefs
   1/*
   2 * net/dsa/dsa.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/list.h>
  13#include <linux/netdevice.h>
  14#include <linux/platform_device.h>
  15#include <linux/slab.h>
  16#include <linux/module.h>
  17#include <net/dsa.h>
  18#include <linux/of.h>
  19#include <linux/of_mdio.h>
  20#include <linux/of_platform.h>
  21#include "dsa_priv.h"
  22
  23char dsa_driver_version[] = "0.1";
  24
  25
  26/* switch driver registration ***********************************************/
  27static DEFINE_MUTEX(dsa_switch_drivers_mutex);
  28static LIST_HEAD(dsa_switch_drivers);
  29
  30void register_switch_driver(struct dsa_switch_driver *drv)
  31{
  32        mutex_lock(&dsa_switch_drivers_mutex);
  33        list_add_tail(&drv->list, &dsa_switch_drivers);
  34        mutex_unlock(&dsa_switch_drivers_mutex);
  35}
  36EXPORT_SYMBOL_GPL(register_switch_driver);
  37
  38void unregister_switch_driver(struct dsa_switch_driver *drv)
  39{
  40        mutex_lock(&dsa_switch_drivers_mutex);
  41        list_del_init(&drv->list);
  42        mutex_unlock(&dsa_switch_drivers_mutex);
  43}
  44EXPORT_SYMBOL_GPL(unregister_switch_driver);
  45
  46static struct dsa_switch_driver *
  47dsa_switch_probe(struct mii_bus *bus, int sw_addr, char **_name)
  48{
  49        struct dsa_switch_driver *ret;
  50        struct list_head *list;
  51        char *name;
  52
  53        ret = NULL;
  54        name = NULL;
  55
  56        mutex_lock(&dsa_switch_drivers_mutex);
  57        list_for_each(list, &dsa_switch_drivers) {
  58                struct dsa_switch_driver *drv;
  59
  60                drv = list_entry(list, struct dsa_switch_driver, list);
  61
  62                name = drv->probe(bus, sw_addr);
  63                if (name != NULL) {
  64                        ret = drv;
  65                        break;
  66                }
  67        }
  68        mutex_unlock(&dsa_switch_drivers_mutex);
  69
  70        *_name = name;
  71
  72        return ret;
  73}
  74
  75
  76/* basic switch operations **************************************************/
  77static struct dsa_switch *
  78dsa_switch_setup(struct dsa_switch_tree *dst, int index,
  79                 struct device *parent, struct mii_bus *bus)
  80{
  81        struct dsa_chip_data *pd = dst->pd->chip + index;
  82        struct dsa_switch_driver *drv;
  83        struct dsa_switch *ds;
  84        int ret;
  85        char *name;
  86        int i;
  87        bool valid_name_found = false;
  88
  89        /*
  90         * Probe for switch model.
  91         */
  92        drv = dsa_switch_probe(bus, pd->sw_addr, &name);
  93        if (drv == NULL) {
  94                printk(KERN_ERR "%s[%d]: could not detect attached switch\n",
  95                       dst->master_netdev->name, index);
  96                return ERR_PTR(-EINVAL);
  97        }
  98        printk(KERN_INFO "%s[%d]: detected a %s switch\n",
  99                dst->master_netdev->name, index, name);
 100
 101
 102        /*
 103         * Allocate and initialise switch state.
 104         */
 105        ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL);
 106        if (ds == NULL)
 107                return ERR_PTR(-ENOMEM);
 108
 109        ds->dst = dst;
 110        ds->index = index;
 111        ds->pd = dst->pd->chip + index;
 112        ds->drv = drv;
 113        ds->master_mii_bus = bus;
 114
 115
 116        /*
 117         * Validate supplied switch configuration.
 118         */
 119        for (i = 0; i < DSA_MAX_PORTS; i++) {
 120                char *name;
 121
 122                name = pd->port_names[i];
 123                if (name == NULL)
 124                        continue;
 125
 126                if (!strcmp(name, "cpu")) {
 127                        if (dst->cpu_switch != -1) {
 128                                printk(KERN_ERR "multiple cpu ports?!\n");
 129                                ret = -EINVAL;
 130                                goto out;
 131                        }
 132                        dst->cpu_switch = index;
 133                        dst->cpu_port = i;
 134                } else if (!strcmp(name, "dsa")) {
 135                        ds->dsa_port_mask |= 1 << i;
 136                } else {
 137                        ds->phys_port_mask |= 1 << i;
 138                }
 139                valid_name_found = true;
 140        }
 141
 142        if (!valid_name_found && i == DSA_MAX_PORTS) {
 143                ret = -EINVAL;
 144                goto out;
 145        }
 146
 147        /*
 148         * If the CPU connects to this switch, set the switch tree
 149         * tagging protocol to the preferred tagging format of this
 150         * switch.
 151         */
 152        if (ds->dst->cpu_switch == index)
 153                ds->dst->tag_protocol = drv->tag_protocol;
 154
 155
 156        /*
 157         * Do basic register setup.
 158         */
 159        ret = drv->setup(ds);
 160        if (ret < 0)
 161                goto out;
 162
 163        ret = drv->set_addr(ds, dst->master_netdev->dev_addr);
 164        if (ret < 0)
 165                goto out;
 166
 167        ds->slave_mii_bus = mdiobus_alloc();
 168        if (ds->slave_mii_bus == NULL) {
 169                ret = -ENOMEM;
 170                goto out;
 171        }
 172        dsa_slave_mii_bus_init(ds);
 173
 174        ret = mdiobus_register(ds->slave_mii_bus);
 175        if (ret < 0)
 176                goto out_free;
 177
 178
 179        /*
 180         * Create network devices for physical switch ports.
 181         */
 182        for (i = 0; i < DSA_MAX_PORTS; i++) {
 183                struct net_device *slave_dev;
 184
 185                if (!(ds->phys_port_mask & (1 << i)))
 186                        continue;
 187
 188                slave_dev = dsa_slave_create(ds, parent, i, pd->port_names[i]);
 189                if (slave_dev == NULL) {
 190                        printk(KERN_ERR "%s[%d]: can't create dsa "
 191                               "slave device for port %d(%s)\n",
 192                               dst->master_netdev->name,
 193                               index, i, pd->port_names[i]);
 194                        continue;
 195                }
 196
 197                ds->ports[i] = slave_dev;
 198        }
 199
 200        return ds;
 201
 202out_free:
 203        mdiobus_free(ds->slave_mii_bus);
 204out:
 205        kfree(ds);
 206        return ERR_PTR(ret);
 207}
 208
 209static void dsa_switch_destroy(struct dsa_switch *ds)
 210{
 211}
 212
 213
 214/* link polling *************************************************************/
 215static void dsa_link_poll_work(struct work_struct *ugly)
 216{
 217        struct dsa_switch_tree *dst;
 218        int i;
 219
 220        dst = container_of(ugly, struct dsa_switch_tree, link_poll_work);
 221
 222        for (i = 0; i < dst->pd->nr_chips; i++) {
 223                struct dsa_switch *ds = dst->ds[i];
 224
 225                if (ds != NULL && ds->drv->poll_link != NULL)
 226                        ds->drv->poll_link(ds);
 227        }
 228
 229        mod_timer(&dst->link_poll_timer, round_jiffies(jiffies + HZ));
 230}
 231
 232static void dsa_link_poll_timer(unsigned long _dst)
 233{
 234        struct dsa_switch_tree *dst = (void *)_dst;
 235
 236        schedule_work(&dst->link_poll_work);
 237}
 238
 239
 240/* platform driver init and cleanup *****************************************/
 241static int dev_is_class(struct device *dev, void *class)
 242{
 243        if (dev->class != NULL && !strcmp(dev->class->name, class))
 244                return 1;
 245
 246        return 0;
 247}
 248
 249static struct device *dev_find_class(struct device *parent, char *class)
 250{
 251        if (dev_is_class(parent, class)) {
 252                get_device(parent);
 253                return parent;
 254        }
 255
 256        return device_find_child(parent, class, dev_is_class);
 257}
 258
 259static struct mii_bus *dev_to_mii_bus(struct device *dev)
 260{
 261        struct device *d;
 262
 263        d = dev_find_class(dev, "mdio_bus");
 264        if (d != NULL) {
 265                struct mii_bus *bus;
 266
 267                bus = to_mii_bus(d);
 268                put_device(d);
 269
 270                return bus;
 271        }
 272
 273        return NULL;
 274}
 275
 276static struct net_device *dev_to_net_device(struct device *dev)
 277{
 278        struct device *d;
 279
 280        d = dev_find_class(dev, "net");
 281        if (d != NULL) {
 282                struct net_device *nd;
 283
 284                nd = to_net_dev(d);
 285                dev_hold(nd);
 286                put_device(d);
 287
 288                return nd;
 289        }
 290
 291        return NULL;
 292}
 293
 294#ifdef CONFIG_OF
 295static int dsa_of_setup_routing_table(struct dsa_platform_data *pd,
 296                                        struct dsa_chip_data *cd,
 297                                        int chip_index,
 298                                        struct device_node *link)
 299{
 300        int ret;
 301        const __be32 *reg;
 302        int link_port_addr;
 303        int link_sw_addr;
 304        struct device_node *parent_sw;
 305        int len;
 306
 307        parent_sw = of_get_parent(link);
 308        if (!parent_sw)
 309                return -EINVAL;
 310
 311        reg = of_get_property(parent_sw, "reg", &len);
 312        if (!reg || (len != sizeof(*reg) * 2))
 313                return -EINVAL;
 314
 315        link_sw_addr = be32_to_cpup(reg + 1);
 316
 317        if (link_sw_addr >= pd->nr_chips)
 318                return -EINVAL;
 319
 320        /* First time routing table allocation */
 321        if (!cd->rtable) {
 322                cd->rtable = kmalloc(pd->nr_chips * sizeof(s8), GFP_KERNEL);
 323                if (!cd->rtable)
 324                        return -ENOMEM;
 325
 326                /* default to no valid uplink/downlink */
 327                memset(cd->rtable, -1, pd->nr_chips * sizeof(s8));
 328        }
 329
 330        reg = of_get_property(link, "reg", NULL);
 331        if (!reg) {
 332                ret = -EINVAL;
 333                goto out;
 334        }
 335
 336        link_port_addr = be32_to_cpup(reg);
 337
 338        cd->rtable[link_sw_addr] = link_port_addr;
 339
 340        return 0;
 341out:
 342        kfree(cd->rtable);
 343        return ret;
 344}
 345
 346static void dsa_of_free_platform_data(struct dsa_platform_data *pd)
 347{
 348        int i;
 349        int port_index;
 350
 351        for (i = 0; i < pd->nr_chips; i++) {
 352                port_index = 0;
 353                while (port_index < DSA_MAX_PORTS) {
 354                        if (pd->chip[i].port_names[port_index])
 355                                kfree(pd->chip[i].port_names[port_index]);
 356                        port_index++;
 357                }
 358                kfree(pd->chip[i].rtable);
 359        }
 360        kfree(pd->chip);
 361}
 362
 363static int dsa_of_probe(struct platform_device *pdev)
 364{
 365        struct device_node *np = pdev->dev.of_node;
 366        struct device_node *child, *mdio, *ethernet, *port, *link;
 367        struct mii_bus *mdio_bus;
 368        struct platform_device *ethernet_dev;
 369        struct dsa_platform_data *pd;
 370        struct dsa_chip_data *cd;
 371        const char *port_name;
 372        int chip_index, port_index;
 373        const unsigned int *sw_addr, *port_reg;
 374        int ret;
 375
 376        mdio = of_parse_phandle(np, "dsa,mii-bus", 0);
 377        if (!mdio)
 378                return -EINVAL;
 379
 380        mdio_bus = of_mdio_find_bus(mdio);
 381        if (!mdio_bus)
 382                return -EINVAL;
 383
 384        ethernet = of_parse_phandle(np, "dsa,ethernet", 0);
 385        if (!ethernet)
 386                return -EINVAL;
 387
 388        ethernet_dev = of_find_device_by_node(ethernet);
 389        if (!ethernet_dev)
 390                return -ENODEV;
 391
 392        pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 393        if (!pd)
 394                return -ENOMEM;
 395
 396        pdev->dev.platform_data = pd;
 397        pd->netdev = &ethernet_dev->dev;
 398        pd->nr_chips = of_get_child_count(np);
 399        if (pd->nr_chips > DSA_MAX_SWITCHES)
 400                pd->nr_chips = DSA_MAX_SWITCHES;
 401
 402        pd->chip = kzalloc(pd->nr_chips * sizeof(struct dsa_chip_data),
 403                        GFP_KERNEL);
 404        if (!pd->chip) {
 405                ret = -ENOMEM;
 406                goto out_free;
 407        }
 408
 409        chip_index = 0;
 410        for_each_available_child_of_node(np, child) {
 411                cd = &pd->chip[chip_index];
 412
 413                cd->mii_bus = &mdio_bus->dev;
 414
 415                sw_addr = of_get_property(child, "reg", NULL);
 416                if (!sw_addr)
 417                        continue;
 418
 419                cd->sw_addr = be32_to_cpup(sw_addr);
 420                if (cd->sw_addr > PHY_MAX_ADDR)
 421                        continue;
 422
 423                for_each_available_child_of_node(child, port) {
 424                        port_reg = of_get_property(port, "reg", NULL);
 425                        if (!port_reg)
 426                                continue;
 427
 428                        port_index = be32_to_cpup(port_reg);
 429
 430                        port_name = of_get_property(port, "label", NULL);
 431                        if (!port_name)
 432                                continue;
 433
 434                        cd->port_names[port_index] = kstrdup(port_name,
 435                                        GFP_KERNEL);
 436                        if (!cd->port_names[port_index]) {
 437                                ret = -ENOMEM;
 438                                goto out_free_chip;
 439                        }
 440
 441                        link = of_parse_phandle(port, "link", 0);
 442
 443                        if (!strcmp(port_name, "dsa") && link &&
 444                                        pd->nr_chips > 1) {
 445                                ret = dsa_of_setup_routing_table(pd, cd,
 446                                                chip_index, link);
 447                                if (ret)
 448                                        goto out_free_chip;
 449                        }
 450
 451                        if (port_index == DSA_MAX_PORTS)
 452                                break;
 453                }
 454        }
 455
 456        return 0;
 457
 458out_free_chip:
 459        dsa_of_free_platform_data(pd);
 460out_free:
 461        kfree(pd);
 462        pdev->dev.platform_data = NULL;
 463        return ret;
 464}
 465
 466static void dsa_of_remove(struct platform_device *pdev)
 467{
 468        struct dsa_platform_data *pd = pdev->dev.platform_data;
 469
 470        if (!pdev->dev.of_node)
 471                return;
 472
 473        dsa_of_free_platform_data(pd);
 474        kfree(pd);
 475}
 476#else
 477static inline int dsa_of_probe(struct platform_device *pdev)
 478{
 479        return 0;
 480}
 481
 482static inline void dsa_of_remove(struct platform_device *pdev)
 483{
 484}
 485#endif
 486
 487static int dsa_probe(struct platform_device *pdev)
 488{
 489        static int dsa_version_printed;
 490        struct dsa_platform_data *pd = pdev->dev.platform_data;
 491        struct net_device *dev;
 492        struct dsa_switch_tree *dst;
 493        int i, ret;
 494
 495        if (!dsa_version_printed++)
 496                printk(KERN_NOTICE "Distributed Switch Architecture "
 497                        "driver version %s\n", dsa_driver_version);
 498
 499        if (pdev->dev.of_node) {
 500                ret = dsa_of_probe(pdev);
 501                if (ret)
 502                        return ret;
 503
 504                pd = pdev->dev.platform_data;
 505        }
 506
 507        if (pd == NULL || pd->netdev == NULL)
 508                return -EINVAL;
 509
 510        dev = dev_to_net_device(pd->netdev);
 511        if (dev == NULL) {
 512                ret = -EINVAL;
 513                goto out;
 514        }
 515
 516        if (dev->dsa_ptr != NULL) {
 517                dev_put(dev);
 518                ret = -EEXIST;
 519                goto out;
 520        }
 521
 522        dst = kzalloc(sizeof(*dst), GFP_KERNEL);
 523        if (dst == NULL) {
 524                dev_put(dev);
 525                ret = -ENOMEM;
 526                goto out;
 527        }
 528
 529        platform_set_drvdata(pdev, dst);
 530
 531        dst->pd = pd;
 532        dst->master_netdev = dev;
 533        dst->cpu_switch = -1;
 534        dst->cpu_port = -1;
 535
 536        for (i = 0; i < pd->nr_chips; i++) {
 537                struct mii_bus *bus;
 538                struct dsa_switch *ds;
 539
 540                bus = dev_to_mii_bus(pd->chip[i].mii_bus);
 541                if (bus == NULL) {
 542                        printk(KERN_ERR "%s[%d]: no mii bus found for "
 543                                "dsa switch\n", dev->name, i);
 544                        continue;
 545                }
 546
 547                ds = dsa_switch_setup(dst, i, &pdev->dev, bus);
 548                if (IS_ERR(ds)) {
 549                        printk(KERN_ERR "%s[%d]: couldn't create dsa switch "
 550                                "instance (error %ld)\n", dev->name, i,
 551                                PTR_ERR(ds));
 552                        continue;
 553                }
 554
 555                dst->ds[i] = ds;
 556                if (ds->drv->poll_link != NULL)
 557                        dst->link_poll_needed = 1;
 558        }
 559
 560        /*
 561         * If we use a tagging format that doesn't have an ethertype
 562         * field, make sure that all packets from this point on get
 563         * sent to the tag format's receive function.
 564         */
 565        wmb();
 566        dev->dsa_ptr = (void *)dst;
 567
 568        if (dst->link_poll_needed) {
 569                INIT_WORK(&dst->link_poll_work, dsa_link_poll_work);
 570                init_timer(&dst->link_poll_timer);
 571                dst->link_poll_timer.data = (unsigned long)dst;
 572                dst->link_poll_timer.function = dsa_link_poll_timer;
 573                dst->link_poll_timer.expires = round_jiffies(jiffies + HZ);
 574                add_timer(&dst->link_poll_timer);
 575        }
 576
 577        return 0;
 578
 579out:
 580        dsa_of_remove(pdev);
 581
 582        return ret;
 583}
 584
 585static int dsa_remove(struct platform_device *pdev)
 586{
 587        struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
 588        int i;
 589
 590        if (dst->link_poll_needed)
 591                del_timer_sync(&dst->link_poll_timer);
 592
 593        flush_work(&dst->link_poll_work);
 594
 595        for (i = 0; i < dst->pd->nr_chips; i++) {
 596                struct dsa_switch *ds = dst->ds[i];
 597
 598                if (ds != NULL)
 599                        dsa_switch_destroy(ds);
 600        }
 601
 602        dsa_of_remove(pdev);
 603
 604        return 0;
 605}
 606
 607static void dsa_shutdown(struct platform_device *pdev)
 608{
 609}
 610
 611static const struct of_device_id dsa_of_match_table[] = {
 612        { .compatible = "marvell,dsa", },
 613        {}
 614};
 615MODULE_DEVICE_TABLE(of, dsa_of_match_table);
 616
 617static struct platform_driver dsa_driver = {
 618        .probe          = dsa_probe,
 619        .remove         = dsa_remove,
 620        .shutdown       = dsa_shutdown,
 621        .driver = {
 622                .name   = "dsa",
 623                .owner  = THIS_MODULE,
 624                .of_match_table = dsa_of_match_table,
 625        },
 626};
 627
 628static int __init dsa_init_module(void)
 629{
 630        int rc;
 631
 632        rc = platform_driver_register(&dsa_driver);
 633        if (rc)
 634                return rc;
 635
 636#ifdef CONFIG_NET_DSA_TAG_DSA
 637        dev_add_pack(&dsa_packet_type);
 638#endif
 639#ifdef CONFIG_NET_DSA_TAG_EDSA
 640        dev_add_pack(&edsa_packet_type);
 641#endif
 642#ifdef CONFIG_NET_DSA_TAG_TRAILER
 643        dev_add_pack(&trailer_packet_type);
 644#endif
 645        return 0;
 646}
 647module_init(dsa_init_module);
 648
 649static void __exit dsa_cleanup_module(void)
 650{
 651#ifdef CONFIG_NET_DSA_TAG_TRAILER
 652        dev_remove_pack(&trailer_packet_type);
 653#endif
 654#ifdef CONFIG_NET_DSA_TAG_EDSA
 655        dev_remove_pack(&edsa_packet_type);
 656#endif
 657#ifdef CONFIG_NET_DSA_TAG_DSA
 658        dev_remove_pack(&dsa_packet_type);
 659#endif
 660        platform_driver_unregister(&dsa_driver);
 661}
 662module_exit(dsa_cleanup_module);
 663
 664MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
 665MODULE_DESCRIPTION("Driver for Distributed Switch Architecture switch chips");
 666MODULE_LICENSE("GPL");
 667MODULE_ALIAS("platform:dsa");
 668