linux/drivers/net/ethernet/marvell/prestera/prestera_main.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
   3
   4#include <linux/etherdevice.h>
   5#include <linux/jiffies.h>
   6#include <linux/list.h>
   7#include <linux/module.h>
   8#include <linux/netdev_features.h>
   9#include <linux/of.h>
  10#include <linux/of_net.h>
  11
  12#include "prestera.h"
  13#include "prestera_hw.h"
  14#include "prestera_rxtx.h"
  15#include "prestera_devlink.h"
  16#include "prestera_ethtool.h"
  17#include "prestera_switchdev.h"
  18
  19#define PRESTERA_MTU_DEFAULT    1536
  20
  21#define PRESTERA_STATS_DELAY_MS 1000
  22
  23#define PRESTERA_MAC_ADDR_NUM_MAX       255
  24
  25static struct workqueue_struct *prestera_wq;
  26
  27int prestera_port_pvid_set(struct prestera_port *port, u16 vid)
  28{
  29        enum prestera_accept_frm_type frm_type;
  30        int err;
  31
  32        frm_type = PRESTERA_ACCEPT_FRAME_TYPE_TAGGED;
  33
  34        if (vid) {
  35                err = prestera_hw_vlan_port_vid_set(port, vid);
  36                if (err)
  37                        return err;
  38
  39                frm_type = PRESTERA_ACCEPT_FRAME_TYPE_ALL;
  40        }
  41
  42        err = prestera_hw_port_accept_frm_type(port, frm_type);
  43        if (err && frm_type == PRESTERA_ACCEPT_FRAME_TYPE_ALL)
  44                prestera_hw_vlan_port_vid_set(port, port->pvid);
  45
  46        port->pvid = vid;
  47        return 0;
  48}
  49
  50struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,
  51                                                 u32 dev_id, u32 hw_id)
  52{
  53        struct prestera_port *port = NULL;
  54
  55        read_lock(&sw->port_list_lock);
  56        list_for_each_entry(port, &sw->port_list, list) {
  57                if (port->dev_id == dev_id && port->hw_id == hw_id)
  58                        break;
  59        }
  60        read_unlock(&sw->port_list_lock);
  61
  62        return port;
  63}
  64
  65struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id)
  66{
  67        struct prestera_port *port = NULL;
  68
  69        read_lock(&sw->port_list_lock);
  70        list_for_each_entry(port, &sw->port_list, list) {
  71                if (port->id == id)
  72                        break;
  73        }
  74        read_unlock(&sw->port_list_lock);
  75
  76        return port;
  77}
  78
  79static int prestera_port_open(struct net_device *dev)
  80{
  81        struct prestera_port *port = netdev_priv(dev);
  82        int err;
  83
  84        err = prestera_hw_port_state_set(port, true);
  85        if (err)
  86                return err;
  87
  88        netif_start_queue(dev);
  89
  90        return 0;
  91}
  92
  93static int prestera_port_close(struct net_device *dev)
  94{
  95        struct prestera_port *port = netdev_priv(dev);
  96        int err;
  97
  98        netif_stop_queue(dev);
  99
 100        err = prestera_hw_port_state_set(port, false);
 101        if (err)
 102                return err;
 103
 104        return 0;
 105}
 106
 107static netdev_tx_t prestera_port_xmit(struct sk_buff *skb,
 108                                      struct net_device *dev)
 109{
 110        return prestera_rxtx_xmit(netdev_priv(dev), skb);
 111}
 112
 113static int prestera_is_valid_mac_addr(struct prestera_port *port, u8 *addr)
 114{
 115        if (!is_valid_ether_addr(addr))
 116                return -EADDRNOTAVAIL;
 117
 118        /* firmware requires that port's MAC address contains first 5 bytes
 119         * of the base MAC address
 120         */
 121        if (memcmp(port->sw->base_mac, addr, ETH_ALEN - 1))
 122                return -EINVAL;
 123
 124        return 0;
 125}
 126
 127static int prestera_port_set_mac_address(struct net_device *dev, void *p)
 128{
 129        struct prestera_port *port = netdev_priv(dev);
 130        struct sockaddr *addr = p;
 131        int err;
 132
 133        err = prestera_is_valid_mac_addr(port, addr->sa_data);
 134        if (err)
 135                return err;
 136
 137        err = prestera_hw_port_mac_set(port, addr->sa_data);
 138        if (err)
 139                return err;
 140
 141        ether_addr_copy(dev->dev_addr, addr->sa_data);
 142
 143        return 0;
 144}
 145
 146static int prestera_port_change_mtu(struct net_device *dev, int mtu)
 147{
 148        struct prestera_port *port = netdev_priv(dev);
 149        int err;
 150
 151        err = prestera_hw_port_mtu_set(port, mtu);
 152        if (err)
 153                return err;
 154
 155        dev->mtu = mtu;
 156
 157        return 0;
 158}
 159
 160static void prestera_port_get_stats64(struct net_device *dev,
 161                                      struct rtnl_link_stats64 *stats)
 162{
 163        struct prestera_port *port = netdev_priv(dev);
 164        struct prestera_port_stats *port_stats = &port->cached_hw_stats.stats;
 165
 166        stats->rx_packets = port_stats->broadcast_frames_received +
 167                                port_stats->multicast_frames_received +
 168                                port_stats->unicast_frames_received;
 169
 170        stats->tx_packets = port_stats->broadcast_frames_sent +
 171                                port_stats->multicast_frames_sent +
 172                                port_stats->unicast_frames_sent;
 173
 174        stats->rx_bytes = port_stats->good_octets_received;
 175
 176        stats->tx_bytes = port_stats->good_octets_sent;
 177
 178        stats->rx_errors = port_stats->rx_error_frame_received;
 179        stats->tx_errors = port_stats->mac_trans_error;
 180
 181        stats->rx_dropped = port_stats->buffer_overrun;
 182        stats->tx_dropped = 0;
 183
 184        stats->multicast = port_stats->multicast_frames_received;
 185        stats->collisions = port_stats->excessive_collision;
 186
 187        stats->rx_crc_errors = port_stats->bad_crc;
 188}
 189
 190static void prestera_port_get_hw_stats(struct prestera_port *port)
 191{
 192        prestera_hw_port_stats_get(port, &port->cached_hw_stats.stats);
 193}
 194
 195static void prestera_port_stats_update(struct work_struct *work)
 196{
 197        struct prestera_port *port =
 198                container_of(work, struct prestera_port,
 199                             cached_hw_stats.caching_dw.work);
 200
 201        prestera_port_get_hw_stats(port);
 202
 203        queue_delayed_work(prestera_wq, &port->cached_hw_stats.caching_dw,
 204                           msecs_to_jiffies(PRESTERA_STATS_DELAY_MS));
 205}
 206
 207static const struct net_device_ops prestera_netdev_ops = {
 208        .ndo_open = prestera_port_open,
 209        .ndo_stop = prestera_port_close,
 210        .ndo_start_xmit = prestera_port_xmit,
 211        .ndo_change_mtu = prestera_port_change_mtu,
 212        .ndo_get_stats64 = prestera_port_get_stats64,
 213        .ndo_set_mac_address = prestera_port_set_mac_address,
 214        .ndo_get_devlink_port = prestera_devlink_get_port,
 215};
 216
 217int prestera_port_autoneg_set(struct prestera_port *port, bool enable,
 218                              u64 adver_link_modes, u8 adver_fec)
 219{
 220        bool refresh = false;
 221        u64 link_modes;
 222        int err;
 223        u8 fec;
 224
 225        if (port->caps.type != PRESTERA_PORT_TYPE_TP)
 226                return enable ? -EINVAL : 0;
 227
 228        if (!enable)
 229                goto set_autoneg;
 230
 231        link_modes = port->caps.supp_link_modes & adver_link_modes;
 232        fec = port->caps.supp_fec & adver_fec;
 233
 234        if (!link_modes && !fec)
 235                return -EOPNOTSUPP;
 236
 237        if (link_modes && port->adver_link_modes != link_modes) {
 238                port->adver_link_modes = link_modes;
 239                refresh = true;
 240        }
 241
 242        if (fec && port->adver_fec != fec) {
 243                port->adver_fec = fec;
 244                refresh = true;
 245        }
 246
 247set_autoneg:
 248        if (port->autoneg == enable && !refresh)
 249                return 0;
 250
 251        err = prestera_hw_port_autoneg_set(port, enable, port->adver_link_modes,
 252                                           port->adver_fec);
 253        if (err)
 254                return err;
 255
 256        port->autoneg = enable;
 257
 258        return 0;
 259}
 260
 261static void prestera_port_list_add(struct prestera_port *port)
 262{
 263        write_lock(&port->sw->port_list_lock);
 264        list_add(&port->list, &port->sw->port_list);
 265        write_unlock(&port->sw->port_list_lock);
 266}
 267
 268static void prestera_port_list_del(struct prestera_port *port)
 269{
 270        write_lock(&port->sw->port_list_lock);
 271        list_del(&port->list);
 272        write_unlock(&port->sw->port_list_lock);
 273}
 274
 275static int prestera_port_create(struct prestera_switch *sw, u32 id)
 276{
 277        struct prestera_port *port;
 278        struct net_device *dev;
 279        int err;
 280
 281        dev = alloc_etherdev(sizeof(*port));
 282        if (!dev)
 283                return -ENOMEM;
 284
 285        port = netdev_priv(dev);
 286
 287        INIT_LIST_HEAD(&port->vlans_list);
 288        port->pvid = PRESTERA_DEFAULT_VID;
 289        port->dev = dev;
 290        port->id = id;
 291        port->sw = sw;
 292
 293        err = prestera_hw_port_info_get(port, &port->dev_id, &port->hw_id,
 294                                        &port->fp_id);
 295        if (err) {
 296                dev_err(prestera_dev(sw), "Failed to get port(%u) info\n", id);
 297                goto err_port_info_get;
 298        }
 299
 300        err = prestera_devlink_port_register(port);
 301        if (err)
 302                goto err_dl_port_register;
 303
 304        dev->features |= NETIF_F_NETNS_LOCAL;
 305        dev->netdev_ops = &prestera_netdev_ops;
 306        dev->ethtool_ops = &prestera_ethtool_ops;
 307
 308        netif_carrier_off(dev);
 309
 310        dev->mtu = min_t(unsigned int, sw->mtu_max, PRESTERA_MTU_DEFAULT);
 311        dev->min_mtu = sw->mtu_min;
 312        dev->max_mtu = sw->mtu_max;
 313
 314        err = prestera_hw_port_mtu_set(port, dev->mtu);
 315        if (err) {
 316                dev_err(prestera_dev(sw), "Failed to set port(%u) mtu(%d)\n",
 317                        id, dev->mtu);
 318                goto err_port_init;
 319        }
 320
 321        if (port->fp_id >= PRESTERA_MAC_ADDR_NUM_MAX) {
 322                err = -EINVAL;
 323                goto err_port_init;
 324        }
 325
 326        /* firmware requires that port's MAC address consist of the first
 327         * 5 bytes of the base MAC address
 328         */
 329        memcpy(dev->dev_addr, sw->base_mac, dev->addr_len - 1);
 330        dev->dev_addr[dev->addr_len - 1] = port->fp_id;
 331
 332        err = prestera_hw_port_mac_set(port, dev->dev_addr);
 333        if (err) {
 334                dev_err(prestera_dev(sw), "Failed to set port(%u) mac addr\n", id);
 335                goto err_port_init;
 336        }
 337
 338        err = prestera_hw_port_cap_get(port, &port->caps);
 339        if (err) {
 340                dev_err(prestera_dev(sw), "Failed to get port(%u) caps\n", id);
 341                goto err_port_init;
 342        }
 343
 344        port->adver_fec = BIT(PRESTERA_PORT_FEC_OFF);
 345        prestera_port_autoneg_set(port, true, port->caps.supp_link_modes,
 346                                  port->caps.supp_fec);
 347
 348        err = prestera_hw_port_state_set(port, false);
 349        if (err) {
 350                dev_err(prestera_dev(sw), "Failed to set port(%u) down\n", id);
 351                goto err_port_init;
 352        }
 353
 354        err = prestera_rxtx_port_init(port);
 355        if (err)
 356                goto err_port_init;
 357
 358        INIT_DELAYED_WORK(&port->cached_hw_stats.caching_dw,
 359                          &prestera_port_stats_update);
 360
 361        prestera_port_list_add(port);
 362
 363        err = register_netdev(dev);
 364        if (err)
 365                goto err_register_netdev;
 366
 367        prestera_devlink_port_set(port);
 368
 369        return 0;
 370
 371err_register_netdev:
 372        prestera_port_list_del(port);
 373err_port_init:
 374        prestera_devlink_port_unregister(port);
 375err_dl_port_register:
 376err_port_info_get:
 377        free_netdev(dev);
 378        return err;
 379}
 380
 381static void prestera_port_destroy(struct prestera_port *port)
 382{
 383        struct net_device *dev = port->dev;
 384
 385        cancel_delayed_work_sync(&port->cached_hw_stats.caching_dw);
 386        prestera_devlink_port_clear(port);
 387        unregister_netdev(dev);
 388        prestera_port_list_del(port);
 389        prestera_devlink_port_unregister(port);
 390        free_netdev(dev);
 391}
 392
 393static void prestera_destroy_ports(struct prestera_switch *sw)
 394{
 395        struct prestera_port *port, *tmp;
 396
 397        list_for_each_entry_safe(port, tmp, &sw->port_list, list)
 398                prestera_port_destroy(port);
 399}
 400
 401static int prestera_create_ports(struct prestera_switch *sw)
 402{
 403        struct prestera_port *port, *tmp;
 404        u32 port_idx;
 405        int err;
 406
 407        for (port_idx = 0; port_idx < sw->port_count; port_idx++) {
 408                err = prestera_port_create(sw, port_idx);
 409                if (err)
 410                        goto err_port_create;
 411        }
 412
 413        return 0;
 414
 415err_port_create:
 416        list_for_each_entry_safe(port, tmp, &sw->port_list, list)
 417                prestera_port_destroy(port);
 418
 419        return err;
 420}
 421
 422static void prestera_port_handle_event(struct prestera_switch *sw,
 423                                       struct prestera_event *evt, void *arg)
 424{
 425        struct delayed_work *caching_dw;
 426        struct prestera_port *port;
 427
 428        port = prestera_find_port(sw, evt->port_evt.port_id);
 429        if (!port || !port->dev)
 430                return;
 431
 432        caching_dw = &port->cached_hw_stats.caching_dw;
 433
 434        if (evt->id == PRESTERA_PORT_EVENT_STATE_CHANGED) {
 435                if (evt->port_evt.data.oper_state) {
 436                        netif_carrier_on(port->dev);
 437                        if (!delayed_work_pending(caching_dw))
 438                                queue_delayed_work(prestera_wq, caching_dw, 0);
 439                } else {
 440                        netif_carrier_off(port->dev);
 441                        if (delayed_work_pending(caching_dw))
 442                                cancel_delayed_work(caching_dw);
 443                }
 444        }
 445}
 446
 447static int prestera_event_handlers_register(struct prestera_switch *sw)
 448{
 449        return prestera_hw_event_handler_register(sw, PRESTERA_EVENT_TYPE_PORT,
 450                                                  prestera_port_handle_event,
 451                                                  NULL);
 452}
 453
 454static void prestera_event_handlers_unregister(struct prestera_switch *sw)
 455{
 456        prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_PORT,
 457                                             prestera_port_handle_event);
 458}
 459
 460static int prestera_switch_set_base_mac_addr(struct prestera_switch *sw)
 461{
 462        struct device_node *base_mac_np;
 463        struct device_node *np;
 464        const char *base_mac;
 465
 466        np = of_find_compatible_node(NULL, NULL, "marvell,prestera");
 467        base_mac_np = of_parse_phandle(np, "base-mac-provider", 0);
 468
 469        base_mac = of_get_mac_address(base_mac_np);
 470        of_node_put(base_mac_np);
 471        if (!IS_ERR(base_mac))
 472                ether_addr_copy(sw->base_mac, base_mac);
 473
 474        if (!is_valid_ether_addr(sw->base_mac)) {
 475                eth_random_addr(sw->base_mac);
 476                dev_info(prestera_dev(sw), "using random base mac address\n");
 477        }
 478
 479        return prestera_hw_switch_mac_set(sw, sw->base_mac);
 480}
 481
 482bool prestera_netdev_check(const struct net_device *dev)
 483{
 484        return dev->netdev_ops == &prestera_netdev_ops;
 485}
 486
 487static int prestera_lower_dev_walk(struct net_device *dev,
 488                                   struct netdev_nested_priv *priv)
 489{
 490        struct prestera_port **pport = (struct prestera_port **)priv->data;
 491
 492        if (prestera_netdev_check(dev)) {
 493                *pport = netdev_priv(dev);
 494                return 1;
 495        }
 496
 497        return 0;
 498}
 499
 500struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev)
 501{
 502        struct prestera_port *port = NULL;
 503        struct netdev_nested_priv priv = {
 504                .data = (void *)&port,
 505        };
 506
 507        if (prestera_netdev_check(dev))
 508                return netdev_priv(dev);
 509
 510        netdev_walk_all_lower_dev(dev, prestera_lower_dev_walk, &priv);
 511
 512        return port;
 513}
 514
 515static int prestera_netdev_port_event(struct net_device *dev,
 516                                      unsigned long event, void *ptr)
 517{
 518        switch (event) {
 519        case NETDEV_PRECHANGEUPPER:
 520        case NETDEV_CHANGEUPPER:
 521                return prestera_bridge_port_event(dev, event, ptr);
 522        default:
 523                return 0;
 524        }
 525}
 526
 527static int prestera_netdev_event_handler(struct notifier_block *nb,
 528                                         unsigned long event, void *ptr)
 529{
 530        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 531        int err = 0;
 532
 533        if (prestera_netdev_check(dev))
 534                err = prestera_netdev_port_event(dev, event, ptr);
 535
 536        return notifier_from_errno(err);
 537}
 538
 539static int prestera_netdev_event_handler_register(struct prestera_switch *sw)
 540{
 541        sw->netdev_nb.notifier_call = prestera_netdev_event_handler;
 542
 543        return register_netdevice_notifier(&sw->netdev_nb);
 544}
 545
 546static void prestera_netdev_event_handler_unregister(struct prestera_switch *sw)
 547{
 548        unregister_netdevice_notifier(&sw->netdev_nb);
 549}
 550
 551static int prestera_switch_init(struct prestera_switch *sw)
 552{
 553        int err;
 554
 555        err = prestera_hw_switch_init(sw);
 556        if (err) {
 557                dev_err(prestera_dev(sw), "Failed to init Switch device\n");
 558                return err;
 559        }
 560
 561        rwlock_init(&sw->port_list_lock);
 562        INIT_LIST_HEAD(&sw->port_list);
 563
 564        err = prestera_switch_set_base_mac_addr(sw);
 565        if (err)
 566                return err;
 567
 568        err = prestera_netdev_event_handler_register(sw);
 569        if (err)
 570                return err;
 571
 572        err = prestera_switchdev_init(sw);
 573        if (err)
 574                goto err_swdev_register;
 575
 576        err = prestera_rxtx_switch_init(sw);
 577        if (err)
 578                goto err_rxtx_register;
 579
 580        err = prestera_event_handlers_register(sw);
 581        if (err)
 582                goto err_handlers_register;
 583
 584        err = prestera_devlink_register(sw);
 585        if (err)
 586                goto err_dl_register;
 587
 588        err = prestera_create_ports(sw);
 589        if (err)
 590                goto err_ports_create;
 591
 592        return 0;
 593
 594err_ports_create:
 595        prestera_devlink_unregister(sw);
 596err_dl_register:
 597        prestera_event_handlers_unregister(sw);
 598err_handlers_register:
 599        prestera_rxtx_switch_fini(sw);
 600err_rxtx_register:
 601        prestera_switchdev_fini(sw);
 602err_swdev_register:
 603        prestera_netdev_event_handler_unregister(sw);
 604        prestera_hw_switch_fini(sw);
 605
 606        return err;
 607}
 608
 609static void prestera_switch_fini(struct prestera_switch *sw)
 610{
 611        prestera_destroy_ports(sw);
 612        prestera_devlink_unregister(sw);
 613        prestera_event_handlers_unregister(sw);
 614        prestera_rxtx_switch_fini(sw);
 615        prestera_switchdev_fini(sw);
 616        prestera_netdev_event_handler_unregister(sw);
 617        prestera_hw_switch_fini(sw);
 618}
 619
 620int prestera_device_register(struct prestera_device *dev)
 621{
 622        struct prestera_switch *sw;
 623        int err;
 624
 625        sw = prestera_devlink_alloc();
 626        if (!sw)
 627                return -ENOMEM;
 628
 629        dev->priv = sw;
 630        sw->dev = dev;
 631
 632        err = prestera_switch_init(sw);
 633        if (err) {
 634                prestera_devlink_free(sw);
 635                return err;
 636        }
 637
 638        return 0;
 639}
 640EXPORT_SYMBOL(prestera_device_register);
 641
 642void prestera_device_unregister(struct prestera_device *dev)
 643{
 644        struct prestera_switch *sw = dev->priv;
 645
 646        prestera_switch_fini(sw);
 647        prestera_devlink_free(sw);
 648}
 649EXPORT_SYMBOL(prestera_device_unregister);
 650
 651static int __init prestera_module_init(void)
 652{
 653        prestera_wq = alloc_workqueue("prestera", 0, 0);
 654        if (!prestera_wq)
 655                return -ENOMEM;
 656
 657        return 0;
 658}
 659
 660static void __exit prestera_module_exit(void)
 661{
 662        destroy_workqueue(prestera_wq);
 663}
 664
 665module_init(prestera_module_init);
 666module_exit(prestera_module_exit);
 667
 668MODULE_LICENSE("Dual BSD/GPL");
 669MODULE_DESCRIPTION("Marvell Prestera switch driver");
 670