linux/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
<<
>>
Prefs
   1/*
   2 * drivers/net/ethernet/mellanox/mlxsw/spectrum.c
   3 * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
   4 * Copyright (c) 2015 Jiri Pirko <jiri@mellanox.com>
   5 * Copyright (c) 2015 Ido Schimmel <idosch@mellanox.com>
   6 * Copyright (c) 2015 Elad Raz <eladr@mellanox.com>
   7 *
   8 * Redistribution and use in source and binary forms, with or without
   9 * modification, are permitted provided that the following conditions are met:
  10 *
  11 * 1. Redistributions of source code must retain the above copyright
  12 *    notice, this list of conditions and the following disclaimer.
  13 * 2. Redistributions in binary form must reproduce the above copyright
  14 *    notice, this list of conditions and the following disclaimer in the
  15 *    documentation and/or other materials provided with the distribution.
  16 * 3. Neither the names of the copyright holders nor the names of its
  17 *    contributors may be used to endorse or promote products derived from
  18 *    this software without specific prior written permission.
  19 *
  20 * Alternatively, this software may be distributed under the terms of the
  21 * GNU General Public License ("GPL") version 2 as published by the Free
  22 * Software Foundation.
  23 *
  24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34 * POSSIBILITY OF SUCH DAMAGE.
  35 */
  36
  37#include <linux/kernel.h>
  38#include <linux/module.h>
  39#include <linux/types.h>
  40#include <linux/netdevice.h>
  41#include <linux/etherdevice.h>
  42#include <linux/ethtool.h>
  43#include <linux/slab.h>
  44#include <linux/device.h>
  45#include <linux/skbuff.h>
  46#include <linux/if_vlan.h>
  47#include <linux/if_bridge.h>
  48#include <linux/workqueue.h>
  49#include <linux/jiffies.h>
  50#include <linux/bitops.h>
  51#include <linux/list.h>
  52#include <net/devlink.h>
  53#include <net/switchdev.h>
  54#include <generated/utsrelease.h>
  55
  56#include "spectrum.h"
  57#include "core.h"
  58#include "reg.h"
  59#include "port.h"
  60#include "trap.h"
  61#include "txheader.h"
  62
  63static const char mlxsw_sp_driver_name[] = "mlxsw_spectrum";
  64static const char mlxsw_sp_driver_version[] = "1.0";
  65
  66/* tx_hdr_version
  67 * Tx header version.
  68 * Must be set to 1.
  69 */
  70MLXSW_ITEM32(tx, hdr, version, 0x00, 28, 4);
  71
  72/* tx_hdr_ctl
  73 * Packet control type.
  74 * 0 - Ethernet control (e.g. EMADs, LACP)
  75 * 1 - Ethernet data
  76 */
  77MLXSW_ITEM32(tx, hdr, ctl, 0x00, 26, 2);
  78
  79/* tx_hdr_proto
  80 * Packet protocol type. Must be set to 1 (Ethernet).
  81 */
  82MLXSW_ITEM32(tx, hdr, proto, 0x00, 21, 3);
  83
  84/* tx_hdr_rx_is_router
  85 * Packet is sent from the router. Valid for data packets only.
  86 */
  87MLXSW_ITEM32(tx, hdr, rx_is_router, 0x00, 19, 1);
  88
  89/* tx_hdr_fid_valid
  90 * Indicates if the 'fid' field is valid and should be used for
  91 * forwarding lookup. Valid for data packets only.
  92 */
  93MLXSW_ITEM32(tx, hdr, fid_valid, 0x00, 16, 1);
  94
  95/* tx_hdr_swid
  96 * Switch partition ID. Must be set to 0.
  97 */
  98MLXSW_ITEM32(tx, hdr, swid, 0x00, 12, 3);
  99
 100/* tx_hdr_control_tclass
 101 * Indicates if the packet should use the control TClass and not one
 102 * of the data TClasses.
 103 */
 104MLXSW_ITEM32(tx, hdr, control_tclass, 0x00, 6, 1);
 105
 106/* tx_hdr_etclass
 107 * Egress TClass to be used on the egress device on the egress port.
 108 */
 109MLXSW_ITEM32(tx, hdr, etclass, 0x00, 0, 4);
 110
 111/* tx_hdr_port_mid
 112 * Destination local port for unicast packets.
 113 * Destination multicast ID for multicast packets.
 114 *
 115 * Control packets are directed to a specific egress port, while data
 116 * packets are transmitted through the CPU port (0) into the switch partition,
 117 * where forwarding rules are applied.
 118 */
 119MLXSW_ITEM32(tx, hdr, port_mid, 0x04, 16, 16);
 120
 121/* tx_hdr_fid
 122 * Forwarding ID used for L2 forwarding lookup. Valid only if 'fid_valid' is
 123 * set, otherwise calculated based on the packet's VID using VID to FID mapping.
 124 * Valid for data packets only.
 125 */
 126MLXSW_ITEM32(tx, hdr, fid, 0x08, 0, 16);
 127
 128/* tx_hdr_type
 129 * 0 - Data packets
 130 * 6 - Control packets
 131 */
 132MLXSW_ITEM32(tx, hdr, type, 0x0C, 0, 4);
 133
 134static void mlxsw_sp_txhdr_construct(struct sk_buff *skb,
 135                                     const struct mlxsw_tx_info *tx_info)
 136{
 137        char *txhdr = skb_push(skb, MLXSW_TXHDR_LEN);
 138
 139        memset(txhdr, 0, MLXSW_TXHDR_LEN);
 140
 141        mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1);
 142        mlxsw_tx_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL);
 143        mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH);
 144        mlxsw_tx_hdr_swid_set(txhdr, 0);
 145        mlxsw_tx_hdr_control_tclass_set(txhdr, 1);
 146        mlxsw_tx_hdr_port_mid_set(txhdr, tx_info->local_port);
 147        mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL);
 148}
 149
 150static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp)
 151{
 152        char spad_pl[MLXSW_REG_SPAD_LEN];
 153        int err;
 154
 155        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(spad), spad_pl);
 156        if (err)
 157                return err;
 158        mlxsw_reg_spad_base_mac_memcpy_from(spad_pl, mlxsw_sp->base_mac);
 159        return 0;
 160}
 161
 162static int mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port *mlxsw_sp_port,
 163                                          bool is_up)
 164{
 165        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 166        char paos_pl[MLXSW_REG_PAOS_LEN];
 167
 168        mlxsw_reg_paos_pack(paos_pl, mlxsw_sp_port->local_port,
 169                            is_up ? MLXSW_PORT_ADMIN_STATUS_UP :
 170                            MLXSW_PORT_ADMIN_STATUS_DOWN);
 171        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(paos), paos_pl);
 172}
 173
 174static int mlxsw_sp_port_oper_status_get(struct mlxsw_sp_port *mlxsw_sp_port,
 175                                         bool *p_is_up)
 176{
 177        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 178        char paos_pl[MLXSW_REG_PAOS_LEN];
 179        u8 oper_status;
 180        int err;
 181
 182        mlxsw_reg_paos_pack(paos_pl, mlxsw_sp_port->local_port, 0);
 183        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(paos), paos_pl);
 184        if (err)
 185                return err;
 186        oper_status = mlxsw_reg_paos_oper_status_get(paos_pl);
 187        *p_is_up = oper_status == MLXSW_PORT_ADMIN_STATUS_UP ? true : false;
 188        return 0;
 189}
 190
 191static int mlxsw_sp_port_dev_addr_set(struct mlxsw_sp_port *mlxsw_sp_port,
 192                                      unsigned char *addr)
 193{
 194        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 195        char ppad_pl[MLXSW_REG_PPAD_LEN];
 196
 197        mlxsw_reg_ppad_pack(ppad_pl, true, mlxsw_sp_port->local_port);
 198        mlxsw_reg_ppad_mac_memcpy_to(ppad_pl, addr);
 199        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppad), ppad_pl);
 200}
 201
 202static int mlxsw_sp_port_dev_addr_init(struct mlxsw_sp_port *mlxsw_sp_port)
 203{
 204        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 205        unsigned char *addr = mlxsw_sp_port->dev->dev_addr;
 206
 207        ether_addr_copy(addr, mlxsw_sp->base_mac);
 208        addr[ETH_ALEN - 1] += mlxsw_sp_port->local_port;
 209        return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr);
 210}
 211
 212static int mlxsw_sp_port_stp_state_set(struct mlxsw_sp_port *mlxsw_sp_port,
 213                                       u16 vid, enum mlxsw_reg_spms_state state)
 214{
 215        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 216        char *spms_pl;
 217        int err;
 218
 219        spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL);
 220        if (!spms_pl)
 221                return -ENOMEM;
 222        mlxsw_reg_spms_pack(spms_pl, mlxsw_sp_port->local_port);
 223        mlxsw_reg_spms_vid_pack(spms_pl, vid, state);
 224        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spms), spms_pl);
 225        kfree(spms_pl);
 226        return err;
 227}
 228
 229static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
 230{
 231        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 232        char pmtu_pl[MLXSW_REG_PMTU_LEN];
 233        int max_mtu;
 234        int err;
 235
 236        mtu += MLXSW_TXHDR_LEN + ETH_HLEN;
 237        mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, 0);
 238        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
 239        if (err)
 240                return err;
 241        max_mtu = mlxsw_reg_pmtu_max_mtu_get(pmtu_pl);
 242
 243        if (mtu > max_mtu)
 244                return -EINVAL;
 245
 246        mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, mtu);
 247        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
 248}
 249
 250static int mlxsw_sp_port_swid_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 swid)
 251{
 252        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 253        char pspa_pl[MLXSW_REG_PSPA_LEN];
 254
 255        mlxsw_reg_pspa_pack(pspa_pl, swid, mlxsw_sp_port->local_port);
 256        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pspa), pspa_pl);
 257}
 258
 259static int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port,
 260                                     bool enable)
 261{
 262        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 263        char svpe_pl[MLXSW_REG_SVPE_LEN];
 264
 265        mlxsw_reg_svpe_pack(svpe_pl, mlxsw_sp_port->local_port, enable);
 266        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svpe), svpe_pl);
 267}
 268
 269int mlxsw_sp_port_vid_to_fid_set(struct mlxsw_sp_port *mlxsw_sp_port,
 270                                 enum mlxsw_reg_svfa_mt mt, bool valid, u16 fid,
 271                                 u16 vid)
 272{
 273        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 274        char svfa_pl[MLXSW_REG_SVFA_LEN];
 275
 276        mlxsw_reg_svfa_pack(svfa_pl, mlxsw_sp_port->local_port, mt, valid,
 277                            fid, vid);
 278        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
 279}
 280
 281static int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
 282                                          u16 vid, bool learn_enable)
 283{
 284        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 285        char *spvmlr_pl;
 286        int err;
 287
 288        spvmlr_pl = kmalloc(MLXSW_REG_SPVMLR_LEN, GFP_KERNEL);
 289        if (!spvmlr_pl)
 290                return -ENOMEM;
 291        mlxsw_reg_spvmlr_pack(spvmlr_pl, mlxsw_sp_port->local_port, vid, vid,
 292                              learn_enable);
 293        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvmlr), spvmlr_pl);
 294        kfree(spvmlr_pl);
 295        return err;
 296}
 297
 298static int
 299mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port *mlxsw_sp_port)
 300{
 301        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 302        char sspr_pl[MLXSW_REG_SSPR_LEN];
 303
 304        mlxsw_reg_sspr_pack(sspr_pl, mlxsw_sp_port->local_port);
 305        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sspr), sspr_pl);
 306}
 307
 308static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
 309                                         u8 local_port, u8 *p_module,
 310                                         u8 *p_width)
 311{
 312        char pmlp_pl[MLXSW_REG_PMLP_LEN];
 313        int err;
 314
 315        mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
 316        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
 317        if (err)
 318                return err;
 319        *p_module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
 320        *p_width = mlxsw_reg_pmlp_width_get(pmlp_pl);
 321        return 0;
 322}
 323
 324static int mlxsw_sp_port_module_map(struct mlxsw_sp *mlxsw_sp, u8 local_port,
 325                                    u8 module, u8 width, u8 lane)
 326{
 327        char pmlp_pl[MLXSW_REG_PMLP_LEN];
 328        int i;
 329
 330        mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
 331        mlxsw_reg_pmlp_width_set(pmlp_pl, width);
 332        for (i = 0; i < width; i++) {
 333                mlxsw_reg_pmlp_module_set(pmlp_pl, i, module);
 334                mlxsw_reg_pmlp_tx_lane_set(pmlp_pl, i, lane + i);  /* Rx & Tx */
 335        }
 336
 337        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
 338}
 339
 340static int mlxsw_sp_port_module_unmap(struct mlxsw_sp *mlxsw_sp, u8 local_port)
 341{
 342        char pmlp_pl[MLXSW_REG_PMLP_LEN];
 343
 344        mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
 345        mlxsw_reg_pmlp_width_set(pmlp_pl, 0);
 346        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
 347}
 348
 349static int mlxsw_sp_port_open(struct net_device *dev)
 350{
 351        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 352        int err;
 353
 354        err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
 355        if (err)
 356                return err;
 357        netif_start_queue(dev);
 358        return 0;
 359}
 360
 361static int mlxsw_sp_port_stop(struct net_device *dev)
 362{
 363        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 364
 365        netif_stop_queue(dev);
 366        return mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
 367}
 368
 369static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
 370                                      struct net_device *dev)
 371{
 372        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 373        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 374        struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
 375        const struct mlxsw_tx_info tx_info = {
 376                .local_port = mlxsw_sp_port->local_port,
 377                .is_emad = false,
 378        };
 379        u64 len;
 380        int err;
 381
 382        if (mlxsw_core_skb_transmit_busy(mlxsw_sp, &tx_info))
 383                return NETDEV_TX_BUSY;
 384
 385        if (unlikely(skb_headroom(skb) < MLXSW_TXHDR_LEN)) {
 386                struct sk_buff *skb_orig = skb;
 387
 388                skb = skb_realloc_headroom(skb, MLXSW_TXHDR_LEN);
 389                if (!skb) {
 390                        this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
 391                        dev_kfree_skb_any(skb_orig);
 392                        return NETDEV_TX_OK;
 393                }
 394        }
 395
 396        if (eth_skb_pad(skb)) {
 397                this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
 398                return NETDEV_TX_OK;
 399        }
 400
 401        mlxsw_sp_txhdr_construct(skb, &tx_info);
 402        len = skb->len;
 403        /* Due to a race we might fail here because of a full queue. In that
 404         * unlikely case we simply drop the packet.
 405         */
 406        err = mlxsw_core_skb_transmit(mlxsw_sp, skb, &tx_info);
 407
 408        if (!err) {
 409                pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
 410                u64_stats_update_begin(&pcpu_stats->syncp);
 411                pcpu_stats->tx_packets++;
 412                pcpu_stats->tx_bytes += len;
 413                u64_stats_update_end(&pcpu_stats->syncp);
 414        } else {
 415                this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
 416                dev_kfree_skb_any(skb);
 417        }
 418        return NETDEV_TX_OK;
 419}
 420
 421static void mlxsw_sp_set_rx_mode(struct net_device *dev)
 422{
 423}
 424
 425static int mlxsw_sp_port_set_mac_address(struct net_device *dev, void *p)
 426{
 427        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 428        struct sockaddr *addr = p;
 429        int err;
 430
 431        if (!is_valid_ether_addr(addr->sa_data))
 432                return -EADDRNOTAVAIL;
 433
 434        err = mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr->sa_data);
 435        if (err)
 436                return err;
 437        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 438        return 0;
 439}
 440
 441static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu)
 442{
 443        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 444        int err;
 445
 446        err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, mtu);
 447        if (err)
 448                return err;
 449        dev->mtu = mtu;
 450        return 0;
 451}
 452
 453static struct rtnl_link_stats64 *
 454mlxsw_sp_port_get_stats64(struct net_device *dev,
 455                          struct rtnl_link_stats64 *stats)
 456{
 457        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 458        struct mlxsw_sp_port_pcpu_stats *p;
 459        u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
 460        u32 tx_dropped = 0;
 461        unsigned int start;
 462        int i;
 463
 464        for_each_possible_cpu(i) {
 465                p = per_cpu_ptr(mlxsw_sp_port->pcpu_stats, i);
 466                do {
 467                        start = u64_stats_fetch_begin_irq(&p->syncp);
 468                        rx_packets      = p->rx_packets;
 469                        rx_bytes        = p->rx_bytes;
 470                        tx_packets      = p->tx_packets;
 471                        tx_bytes        = p->tx_bytes;
 472                } while (u64_stats_fetch_retry_irq(&p->syncp, start));
 473
 474                stats->rx_packets       += rx_packets;
 475                stats->rx_bytes         += rx_bytes;
 476                stats->tx_packets       += tx_packets;
 477                stats->tx_bytes         += tx_bytes;
 478                /* tx_dropped is u32, updated without syncp protection. */
 479                tx_dropped      += p->tx_dropped;
 480        }
 481        stats->tx_dropped       = tx_dropped;
 482        return stats;
 483}
 484
 485int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin,
 486                           u16 vid_end, bool is_member, bool untagged)
 487{
 488        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 489        char *spvm_pl;
 490        int err;
 491
 492        spvm_pl = kmalloc(MLXSW_REG_SPVM_LEN, GFP_KERNEL);
 493        if (!spvm_pl)
 494                return -ENOMEM;
 495
 496        mlxsw_reg_spvm_pack(spvm_pl, mlxsw_sp_port->local_port, vid_begin,
 497                            vid_end, is_member, untagged);
 498        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvm), spvm_pl);
 499        kfree(spvm_pl);
 500        return err;
 501}
 502
 503static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
 504{
 505        enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
 506        u16 vid, last_visited_vid;
 507        int err;
 508
 509        for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) {
 510                err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_port, mt, true, vid,
 511                                                   vid);
 512                if (err) {
 513                        last_visited_vid = vid;
 514                        goto err_port_vid_to_fid_set;
 515                }
 516        }
 517
 518        err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true);
 519        if (err) {
 520                last_visited_vid = VLAN_N_VID;
 521                goto err_port_vid_to_fid_set;
 522        }
 523
 524        return 0;
 525
 526err_port_vid_to_fid_set:
 527        for_each_set_bit(vid, mlxsw_sp_port->active_vlans, last_visited_vid)
 528                mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_port, mt, false, vid,
 529                                             vid);
 530        return err;
 531}
 532
 533static int mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
 534{
 535        enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
 536        u16 vid;
 537        int err;
 538
 539        err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
 540        if (err)
 541                return err;
 542
 543        for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) {
 544                err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_port, mt, false,
 545                                                   vid, vid);
 546                if (err)
 547                        return err;
 548        }
 549
 550        return 0;
 551}
 552
 553static struct mlxsw_sp_vfid *
 554mlxsw_sp_vfid_find(const struct mlxsw_sp *mlxsw_sp, u16 vid)
 555{
 556        struct mlxsw_sp_vfid *vfid;
 557
 558        list_for_each_entry(vfid, &mlxsw_sp->port_vfids.list, list) {
 559                if (vfid->vid == vid)
 560                        return vfid;
 561        }
 562
 563        return NULL;
 564}
 565
 566static u16 mlxsw_sp_avail_vfid_get(const struct mlxsw_sp *mlxsw_sp)
 567{
 568        return find_first_zero_bit(mlxsw_sp->port_vfids.mapped,
 569                                   MLXSW_SP_VFID_PORT_MAX);
 570}
 571
 572static int __mlxsw_sp_vfid_create(struct mlxsw_sp *mlxsw_sp, u16 vfid)
 573{
 574        u16 fid = mlxsw_sp_vfid_to_fid(vfid);
 575        char sfmr_pl[MLXSW_REG_SFMR_LEN];
 576
 577        mlxsw_reg_sfmr_pack(sfmr_pl, MLXSW_REG_SFMR_OP_CREATE_FID, fid, 0);
 578        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
 579}
 580
 581static void __mlxsw_sp_vfid_destroy(struct mlxsw_sp *mlxsw_sp, u16 vfid)
 582{
 583        u16 fid = mlxsw_sp_vfid_to_fid(vfid);
 584        char sfmr_pl[MLXSW_REG_SFMR_LEN];
 585
 586        mlxsw_reg_sfmr_pack(sfmr_pl, MLXSW_REG_SFMR_OP_DESTROY_FID, fid, 0);
 587        mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
 588}
 589
 590static struct mlxsw_sp_vfid *mlxsw_sp_vfid_create(struct mlxsw_sp *mlxsw_sp,
 591                                                  u16 vid)
 592{
 593        struct device *dev = mlxsw_sp->bus_info->dev;
 594        struct mlxsw_sp_vfid *vfid;
 595        u16 n_vfid;
 596        int err;
 597
 598        n_vfid = mlxsw_sp_avail_vfid_get(mlxsw_sp);
 599        if (n_vfid == MLXSW_SP_VFID_PORT_MAX) {
 600                dev_err(dev, "No available vFIDs\n");
 601                return ERR_PTR(-ERANGE);
 602        }
 603
 604        err = __mlxsw_sp_vfid_create(mlxsw_sp, n_vfid);
 605        if (err) {
 606                dev_err(dev, "Failed to create vFID=%d\n", n_vfid);
 607                return ERR_PTR(err);
 608        }
 609
 610        vfid = kzalloc(sizeof(*vfid), GFP_KERNEL);
 611        if (!vfid)
 612                goto err_allocate_vfid;
 613
 614        vfid->vfid = n_vfid;
 615        vfid->vid = vid;
 616
 617        list_add(&vfid->list, &mlxsw_sp->port_vfids.list);
 618        set_bit(n_vfid, mlxsw_sp->port_vfids.mapped);
 619
 620        return vfid;
 621
 622err_allocate_vfid:
 623        __mlxsw_sp_vfid_destroy(mlxsw_sp, n_vfid);
 624        return ERR_PTR(-ENOMEM);
 625}
 626
 627static void mlxsw_sp_vfid_destroy(struct mlxsw_sp *mlxsw_sp,
 628                                  struct mlxsw_sp_vfid *vfid)
 629{
 630        clear_bit(vfid->vfid, mlxsw_sp->port_vfids.mapped);
 631        list_del(&vfid->list);
 632
 633        __mlxsw_sp_vfid_destroy(mlxsw_sp, vfid->vfid);
 634
 635        kfree(vfid);
 636}
 637
 638static struct mlxsw_sp_port *
 639mlxsw_sp_port_vport_create(struct mlxsw_sp_port *mlxsw_sp_port,
 640                           struct mlxsw_sp_vfid *vfid)
 641{
 642        struct mlxsw_sp_port *mlxsw_sp_vport;
 643
 644        mlxsw_sp_vport = kzalloc(sizeof(*mlxsw_sp_vport), GFP_KERNEL);
 645        if (!mlxsw_sp_vport)
 646                return NULL;
 647
 648        /* dev will be set correctly after the VLAN device is linked
 649         * with the real device. In case of bridge SELF invocation, dev
 650         * will remain as is.
 651         */
 652        mlxsw_sp_vport->dev = mlxsw_sp_port->dev;
 653        mlxsw_sp_vport->mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 654        mlxsw_sp_vport->local_port = mlxsw_sp_port->local_port;
 655        mlxsw_sp_vport->stp_state = BR_STATE_FORWARDING;
 656        mlxsw_sp_vport->lagged = mlxsw_sp_port->lagged;
 657        mlxsw_sp_vport->lag_id = mlxsw_sp_port->lag_id;
 658        mlxsw_sp_vport->vport.vfid = vfid;
 659        mlxsw_sp_vport->vport.vid = vfid->vid;
 660
 661        list_add(&mlxsw_sp_vport->vport.list, &mlxsw_sp_port->vports_list);
 662
 663        return mlxsw_sp_vport;
 664}
 665
 666static void mlxsw_sp_port_vport_destroy(struct mlxsw_sp_port *mlxsw_sp_vport)
 667{
 668        list_del(&mlxsw_sp_vport->vport.list);
 669        kfree(mlxsw_sp_vport);
 670}
 671
 672int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto,
 673                          u16 vid)
 674{
 675        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 676        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 677        struct mlxsw_sp_port *mlxsw_sp_vport;
 678        struct mlxsw_sp_vfid *vfid;
 679        int err;
 680
 681        /* VLAN 0 is added to HW filter when device goes up, but it is
 682         * reserved in our case, so simply return.
 683         */
 684        if (!vid)
 685                return 0;
 686
 687        if (mlxsw_sp_port_vport_find(mlxsw_sp_port, vid)) {
 688                netdev_warn(dev, "VID=%d already configured\n", vid);
 689                return 0;
 690        }
 691
 692        vfid = mlxsw_sp_vfid_find(mlxsw_sp, vid);
 693        if (!vfid) {
 694                vfid = mlxsw_sp_vfid_create(mlxsw_sp, vid);
 695                if (IS_ERR(vfid)) {
 696                        netdev_err(dev, "Failed to create vFID for VID=%d\n",
 697                                   vid);
 698                        return PTR_ERR(vfid);
 699                }
 700        }
 701
 702        mlxsw_sp_vport = mlxsw_sp_port_vport_create(mlxsw_sp_port, vfid);
 703        if (!mlxsw_sp_vport) {
 704                netdev_err(dev, "Failed to create vPort for VID=%d\n", vid);
 705                err = -ENOMEM;
 706                goto err_port_vport_create;
 707        }
 708
 709        if (!vfid->nr_vports) {
 710                err = mlxsw_sp_vport_flood_set(mlxsw_sp_vport, vfid->vfid,
 711                                               true, false);
 712                if (err) {
 713                        netdev_err(dev, "Failed to setup flooding for vFID=%d\n",
 714                                   vfid->vfid);
 715                        goto err_vport_flood_set;
 716                }
 717        }
 718
 719        /* When adding the first VLAN interface on a bridged port we need to
 720         * transition all the active 802.1Q bridge VLANs to use explicit
 721         * {Port, VID} to FID mappings and set the port's mode to Virtual mode.
 722         */
 723        if (list_is_singular(&mlxsw_sp_port->vports_list)) {
 724                err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
 725                if (err) {
 726                        netdev_err(dev, "Failed to set to Virtual mode\n");
 727                        goto err_port_vp_mode_trans;
 728                }
 729        }
 730
 731        err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport,
 732                                           MLXSW_REG_SVFA_MT_PORT_VID_TO_FID,
 733                                           true,
 734                                           mlxsw_sp_vfid_to_fid(vfid->vfid),
 735                                           vid);
 736        if (err) {
 737                netdev_err(dev, "Failed to map {Port, VID=%d} to vFID=%d\n",
 738                           vid, vfid->vfid);
 739                goto err_port_vid_to_fid_set;
 740        }
 741
 742        err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false);
 743        if (err) {
 744                netdev_err(dev, "Failed to disable learning for VID=%d\n", vid);
 745                goto err_port_vid_learning_set;
 746        }
 747
 748        err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, true, false);
 749        if (err) {
 750                netdev_err(dev, "Failed to set VLAN membership for VID=%d\n",
 751                           vid);
 752                goto err_port_add_vid;
 753        }
 754
 755        err = mlxsw_sp_port_stp_state_set(mlxsw_sp_vport, vid,
 756                                          MLXSW_REG_SPMS_STATE_FORWARDING);
 757        if (err) {
 758                netdev_err(dev, "Failed to set STP state for VID=%d\n", vid);
 759                goto err_port_stp_state_set;
 760        }
 761
 762        vfid->nr_vports++;
 763
 764        return 0;
 765
 766err_port_stp_state_set:
 767        mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false);
 768err_port_add_vid:
 769        mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
 770err_port_vid_learning_set:
 771        mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport,
 772                                     MLXSW_REG_SVFA_MT_PORT_VID_TO_FID, false,
 773                                     mlxsw_sp_vfid_to_fid(vfid->vfid), vid);
 774err_port_vid_to_fid_set:
 775        if (list_is_singular(&mlxsw_sp_port->vports_list))
 776                mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
 777err_port_vp_mode_trans:
 778        if (!vfid->nr_vports)
 779                mlxsw_sp_vport_flood_set(mlxsw_sp_vport, vfid->vfid, false,
 780                                         false);
 781err_vport_flood_set:
 782        mlxsw_sp_port_vport_destroy(mlxsw_sp_vport);
 783err_port_vport_create:
 784        if (!vfid->nr_vports)
 785                mlxsw_sp_vfid_destroy(mlxsw_sp, vfid);
 786        return err;
 787}
 788
 789int mlxsw_sp_port_kill_vid(struct net_device *dev,
 790                           __be16 __always_unused proto, u16 vid)
 791{
 792        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 793        struct mlxsw_sp_port *mlxsw_sp_vport;
 794        struct mlxsw_sp_vfid *vfid;
 795        int err;
 796
 797        /* VLAN 0 is removed from HW filter when device goes down, but
 798         * it is reserved in our case, so simply return.
 799         */
 800        if (!vid)
 801                return 0;
 802
 803        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
 804        if (!mlxsw_sp_vport) {
 805                netdev_warn(dev, "VID=%d does not exist\n", vid);
 806                return 0;
 807        }
 808
 809        vfid = mlxsw_sp_vport->vport.vfid;
 810
 811        err = mlxsw_sp_port_stp_state_set(mlxsw_sp_vport, vid,
 812                                          MLXSW_REG_SPMS_STATE_DISCARDING);
 813        if (err) {
 814                netdev_err(dev, "Failed to set STP state for VID=%d\n", vid);
 815                return err;
 816        }
 817
 818        err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false);
 819        if (err) {
 820                netdev_err(dev, "Failed to set VLAN membership for VID=%d\n",
 821                           vid);
 822                return err;
 823        }
 824
 825        err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
 826        if (err) {
 827                netdev_err(dev, "Failed to enable learning for VID=%d\n", vid);
 828                return err;
 829        }
 830
 831        err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport,
 832                                           MLXSW_REG_SVFA_MT_PORT_VID_TO_FID,
 833                                           false,
 834                                           mlxsw_sp_vfid_to_fid(vfid->vfid),
 835                                           vid);
 836        if (err) {
 837                netdev_err(dev, "Failed to invalidate {Port, VID=%d} to vFID=%d mapping\n",
 838                           vid, vfid->vfid);
 839                return err;
 840        }
 841
 842        /* When removing the last VLAN interface on a bridged port we need to
 843         * transition all active 802.1Q bridge VLANs to use VID to FID
 844         * mappings and set port's mode to VLAN mode.
 845         */
 846        if (list_is_singular(&mlxsw_sp_port->vports_list)) {
 847                err = mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
 848                if (err) {
 849                        netdev_err(dev, "Failed to set to VLAN mode\n");
 850                        return err;
 851                }
 852        }
 853
 854        vfid->nr_vports--;
 855        mlxsw_sp_port_vport_destroy(mlxsw_sp_vport);
 856
 857        /* Destroy the vFID if no vPorts are assigned to it anymore. */
 858        if (!vfid->nr_vports)
 859                mlxsw_sp_vfid_destroy(mlxsw_sp_port->mlxsw_sp, vfid);
 860
 861        return 0;
 862}
 863
 864static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
 865        .ndo_open               = mlxsw_sp_port_open,
 866        .ndo_stop               = mlxsw_sp_port_stop,
 867        .ndo_start_xmit         = mlxsw_sp_port_xmit,
 868        .ndo_set_rx_mode        = mlxsw_sp_set_rx_mode,
 869        .ndo_set_mac_address    = mlxsw_sp_port_set_mac_address,
 870        .ndo_change_mtu         = mlxsw_sp_port_change_mtu,
 871        .ndo_get_stats64        = mlxsw_sp_port_get_stats64,
 872        .ndo_vlan_rx_add_vid    = mlxsw_sp_port_add_vid,
 873        .ndo_vlan_rx_kill_vid   = mlxsw_sp_port_kill_vid,
 874        .ndo_fdb_add            = switchdev_port_fdb_add,
 875        .ndo_fdb_del            = switchdev_port_fdb_del,
 876        .ndo_fdb_dump           = switchdev_port_fdb_dump,
 877        .ndo_bridge_setlink     = switchdev_port_bridge_setlink,
 878        .ndo_bridge_getlink     = switchdev_port_bridge_getlink,
 879        .ndo_bridge_dellink     = switchdev_port_bridge_dellink,
 880};
 881
 882static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
 883                                      struct ethtool_drvinfo *drvinfo)
 884{
 885        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 886        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 887
 888        strlcpy(drvinfo->driver, mlxsw_sp_driver_name, sizeof(drvinfo->driver));
 889        strlcpy(drvinfo->version, mlxsw_sp_driver_version,
 890                sizeof(drvinfo->version));
 891        snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
 892                 "%d.%d.%d",
 893                 mlxsw_sp->bus_info->fw_rev.major,
 894                 mlxsw_sp->bus_info->fw_rev.minor,
 895                 mlxsw_sp->bus_info->fw_rev.subminor);
 896        strlcpy(drvinfo->bus_info, mlxsw_sp->bus_info->device_name,
 897                sizeof(drvinfo->bus_info));
 898}
 899
 900struct mlxsw_sp_port_hw_stats {
 901        char str[ETH_GSTRING_LEN];
 902        u64 (*getter)(char *payload);
 903};
 904
 905static const struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = {
 906        {
 907                .str = "a_frames_transmitted_ok",
 908                .getter = mlxsw_reg_ppcnt_a_frames_transmitted_ok_get,
 909        },
 910        {
 911                .str = "a_frames_received_ok",
 912                .getter = mlxsw_reg_ppcnt_a_frames_received_ok_get,
 913        },
 914        {
 915                .str = "a_frame_check_sequence_errors",
 916                .getter = mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get,
 917        },
 918        {
 919                .str = "a_alignment_errors",
 920                .getter = mlxsw_reg_ppcnt_a_alignment_errors_get,
 921        },
 922        {
 923                .str = "a_octets_transmitted_ok",
 924                .getter = mlxsw_reg_ppcnt_a_octets_transmitted_ok_get,
 925        },
 926        {
 927                .str = "a_octets_received_ok",
 928                .getter = mlxsw_reg_ppcnt_a_octets_received_ok_get,
 929        },
 930        {
 931                .str = "a_multicast_frames_xmitted_ok",
 932                .getter = mlxsw_reg_ppcnt_a_multicast_frames_xmitted_ok_get,
 933        },
 934        {
 935                .str = "a_broadcast_frames_xmitted_ok",
 936                .getter = mlxsw_reg_ppcnt_a_broadcast_frames_xmitted_ok_get,
 937        },
 938        {
 939                .str = "a_multicast_frames_received_ok",
 940                .getter = mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get,
 941        },
 942        {
 943                .str = "a_broadcast_frames_received_ok",
 944                .getter = mlxsw_reg_ppcnt_a_broadcast_frames_received_ok_get,
 945        },
 946        {
 947                .str = "a_in_range_length_errors",
 948                .getter = mlxsw_reg_ppcnt_a_in_range_length_errors_get,
 949        },
 950        {
 951                .str = "a_out_of_range_length_field",
 952                .getter = mlxsw_reg_ppcnt_a_out_of_range_length_field_get,
 953        },
 954        {
 955                .str = "a_frame_too_long_errors",
 956                .getter = mlxsw_reg_ppcnt_a_frame_too_long_errors_get,
 957        },
 958        {
 959                .str = "a_symbol_error_during_carrier",
 960                .getter = mlxsw_reg_ppcnt_a_symbol_error_during_carrier_get,
 961        },
 962        {
 963                .str = "a_mac_control_frames_transmitted",
 964                .getter = mlxsw_reg_ppcnt_a_mac_control_frames_transmitted_get,
 965        },
 966        {
 967                .str = "a_mac_control_frames_received",
 968                .getter = mlxsw_reg_ppcnt_a_mac_control_frames_received_get,
 969        },
 970        {
 971                .str = "a_unsupported_opcodes_received",
 972                .getter = mlxsw_reg_ppcnt_a_unsupported_opcodes_received_get,
 973        },
 974        {
 975                .str = "a_pause_mac_ctrl_frames_received",
 976                .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_received_get,
 977        },
 978        {
 979                .str = "a_pause_mac_ctrl_frames_xmitted",
 980                .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_transmitted_get,
 981        },
 982};
 983
 984#define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats)
 985
 986static void mlxsw_sp_port_get_strings(struct net_device *dev,
 987                                      u32 stringset, u8 *data)
 988{
 989        u8 *p = data;
 990        int i;
 991
 992        switch (stringset) {
 993        case ETH_SS_STATS:
 994                for (i = 0; i < MLXSW_SP_PORT_HW_STATS_LEN; i++) {
 995                        memcpy(p, mlxsw_sp_port_hw_stats[i].str,
 996                               ETH_GSTRING_LEN);
 997                        p += ETH_GSTRING_LEN;
 998                }
 999                break;
1000        }
1001}
1002
1003static int mlxsw_sp_port_set_phys_id(struct net_device *dev,
1004                                     enum ethtool_phys_id_state state)
1005{
1006        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1007        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1008        char mlcr_pl[MLXSW_REG_MLCR_LEN];
1009        bool active;
1010
1011        switch (state) {
1012        case ETHTOOL_ID_ACTIVE:
1013                active = true;
1014                break;
1015        case ETHTOOL_ID_INACTIVE:
1016                active = false;
1017                break;
1018        default:
1019                return -EOPNOTSUPP;
1020        }
1021
1022        mlxsw_reg_mlcr_pack(mlcr_pl, mlxsw_sp_port->local_port, active);
1023        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mlcr), mlcr_pl);
1024}
1025
1026static void mlxsw_sp_port_get_stats(struct net_device *dev,
1027                                    struct ethtool_stats *stats, u64 *data)
1028{
1029        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1030        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1031        char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
1032        int i;
1033        int err;
1034
1035        mlxsw_reg_ppcnt_pack(ppcnt_pl, mlxsw_sp_port->local_port);
1036        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ppcnt), ppcnt_pl);
1037        for (i = 0; i < MLXSW_SP_PORT_HW_STATS_LEN; i++)
1038                data[i] = !err ? mlxsw_sp_port_hw_stats[i].getter(ppcnt_pl) : 0;
1039}
1040
1041static int mlxsw_sp_port_get_sset_count(struct net_device *dev, int sset)
1042{
1043        switch (sset) {
1044        case ETH_SS_STATS:
1045                return MLXSW_SP_PORT_HW_STATS_LEN;
1046        default:
1047                return -EOPNOTSUPP;
1048        }
1049}
1050
1051struct mlxsw_sp_port_link_mode {
1052        u32 mask;
1053        u32 supported;
1054        u32 advertised;
1055        u32 speed;
1056};
1057
1058static const struct mlxsw_sp_port_link_mode mlxsw_sp_port_link_mode[] = {
1059        {
1060                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100BASE_T,
1061                .supported      = SUPPORTED_100baseT_Full,
1062                .advertised     = ADVERTISED_100baseT_Full,
1063                .speed          = 100,
1064        },
1065        {
1066                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100BASE_TX,
1067                .speed          = 100,
1068        },
1069        {
1070                .mask           = MLXSW_REG_PTYS_ETH_SPEED_SGMII |
1071                                  MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX,
1072                .supported      = SUPPORTED_1000baseKX_Full,
1073                .advertised     = ADVERTISED_1000baseKX_Full,
1074                .speed          = 1000,
1075        },
1076        {
1077                .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_T,
1078                .supported      = SUPPORTED_10000baseT_Full,
1079                .advertised     = ADVERTISED_10000baseT_Full,
1080                .speed          = 10000,
1081        },
1082        {
1083                .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 |
1084                                  MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4,
1085                .supported      = SUPPORTED_10000baseKX4_Full,
1086                .advertised     = ADVERTISED_10000baseKX4_Full,
1087                .speed          = 10000,
1088        },
1089        {
1090                .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
1091                                  MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
1092                                  MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
1093                                  MLXSW_REG_PTYS_ETH_SPEED_10GBASE_ER_LR,
1094                .supported      = SUPPORTED_10000baseKR_Full,
1095                .advertised     = ADVERTISED_10000baseKR_Full,
1096                .speed          = 10000,
1097        },
1098        {
1099                .mask           = MLXSW_REG_PTYS_ETH_SPEED_20GBASE_KR2,
1100                .supported      = SUPPORTED_20000baseKR2_Full,
1101                .advertised     = ADVERTISED_20000baseKR2_Full,
1102                .speed          = 20000,
1103        },
1104        {
1105                .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4,
1106                .supported      = SUPPORTED_40000baseCR4_Full,
1107                .advertised     = ADVERTISED_40000baseCR4_Full,
1108                .speed          = 40000,
1109        },
1110        {
1111                .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4,
1112                .supported      = SUPPORTED_40000baseKR4_Full,
1113                .advertised     = ADVERTISED_40000baseKR4_Full,
1114                .speed          = 40000,
1115        },
1116        {
1117                .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4,
1118                .supported      = SUPPORTED_40000baseSR4_Full,
1119                .advertised     = ADVERTISED_40000baseSR4_Full,
1120                .speed          = 40000,
1121        },
1122        {
1123                .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_LR4_ER4,
1124                .supported      = SUPPORTED_40000baseLR4_Full,
1125                .advertised     = ADVERTISED_40000baseLR4_Full,
1126                .speed          = 40000,
1127        },
1128        {
1129                .mask           = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR |
1130                                  MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR |
1131                                  MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR,
1132                .speed          = 25000,
1133        },
1134        {
1135                .mask           = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR4 |
1136                                  MLXSW_REG_PTYS_ETH_SPEED_50GBASE_CR2 |
1137                                  MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR2,
1138                .speed          = 50000,
1139        },
1140        {
1141                .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
1142                .supported      = SUPPORTED_56000baseKR4_Full,
1143                .advertised     = ADVERTISED_56000baseKR4_Full,
1144                .speed          = 56000,
1145        },
1146        {
1147                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4 |
1148                                  MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
1149                                  MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 |
1150                                  MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4,
1151                .speed          = 100000,
1152        },
1153};
1154
1155#define MLXSW_SP_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp_port_link_mode)
1156
1157static u32 mlxsw_sp_from_ptys_supported_port(u32 ptys_eth_proto)
1158{
1159        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
1160                              MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
1161                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 |
1162                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 |
1163                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
1164                              MLXSW_REG_PTYS_ETH_SPEED_SGMII))
1165                return SUPPORTED_FIBRE;
1166
1167        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
1168                              MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 |
1169                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 |
1170                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 |
1171                              MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX))
1172                return SUPPORTED_Backplane;
1173        return 0;
1174}
1175
1176static u32 mlxsw_sp_from_ptys_supported_link(u32 ptys_eth_proto)
1177{
1178        u32 modes = 0;
1179        int i;
1180
1181        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1182                if (ptys_eth_proto & mlxsw_sp_port_link_mode[i].mask)
1183                        modes |= mlxsw_sp_port_link_mode[i].supported;
1184        }
1185        return modes;
1186}
1187
1188static u32 mlxsw_sp_from_ptys_advert_link(u32 ptys_eth_proto)
1189{
1190        u32 modes = 0;
1191        int i;
1192
1193        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1194                if (ptys_eth_proto & mlxsw_sp_port_link_mode[i].mask)
1195                        modes |= mlxsw_sp_port_link_mode[i].advertised;
1196        }
1197        return modes;
1198}
1199
1200static void mlxsw_sp_from_ptys_speed_duplex(bool carrier_ok, u32 ptys_eth_proto,
1201                                            struct ethtool_cmd *cmd)
1202{
1203        u32 speed = SPEED_UNKNOWN;
1204        u8 duplex = DUPLEX_UNKNOWN;
1205        int i;
1206
1207        if (!carrier_ok)
1208                goto out;
1209
1210        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1211                if (ptys_eth_proto & mlxsw_sp_port_link_mode[i].mask) {
1212                        speed = mlxsw_sp_port_link_mode[i].speed;
1213                        duplex = DUPLEX_FULL;
1214                        break;
1215                }
1216        }
1217out:
1218        ethtool_cmd_speed_set(cmd, speed);
1219        cmd->duplex = duplex;
1220}
1221
1222static u8 mlxsw_sp_port_connector_port(u32 ptys_eth_proto)
1223{
1224        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
1225                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 |
1226                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
1227                              MLXSW_REG_PTYS_ETH_SPEED_SGMII))
1228                return PORT_FIBRE;
1229
1230        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
1231                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 |
1232                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4))
1233                return PORT_DA;
1234
1235        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
1236                              MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 |
1237                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 |
1238                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4))
1239                return PORT_NONE;
1240
1241        return PORT_OTHER;
1242}
1243
1244static int mlxsw_sp_port_get_settings(struct net_device *dev,
1245                                      struct ethtool_cmd *cmd)
1246{
1247        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1248        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1249        char ptys_pl[MLXSW_REG_PTYS_LEN];
1250        u32 eth_proto_cap;
1251        u32 eth_proto_admin;
1252        u32 eth_proto_oper;
1253        int err;
1254
1255        mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port, 0);
1256        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
1257        if (err) {
1258                netdev_err(dev, "Failed to get proto");
1259                return err;
1260        }
1261        mlxsw_reg_ptys_unpack(ptys_pl, &eth_proto_cap,
1262                              &eth_proto_admin, &eth_proto_oper);
1263
1264        cmd->supported = mlxsw_sp_from_ptys_supported_port(eth_proto_cap) |
1265                         mlxsw_sp_from_ptys_supported_link(eth_proto_cap) |
1266                         SUPPORTED_Pause | SUPPORTED_Asym_Pause;
1267        cmd->advertising = mlxsw_sp_from_ptys_advert_link(eth_proto_admin);
1268        mlxsw_sp_from_ptys_speed_duplex(netif_carrier_ok(dev),
1269                                        eth_proto_oper, cmd);
1270
1271        eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
1272        cmd->port = mlxsw_sp_port_connector_port(eth_proto_oper);
1273        cmd->lp_advertising = mlxsw_sp_from_ptys_advert_link(eth_proto_oper);
1274
1275        cmd->transceiver = XCVR_INTERNAL;
1276        return 0;
1277}
1278
1279static u32 mlxsw_sp_to_ptys_advert_link(u32 advertising)
1280{
1281        u32 ptys_proto = 0;
1282        int i;
1283
1284        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1285                if (advertising & mlxsw_sp_port_link_mode[i].advertised)
1286                        ptys_proto |= mlxsw_sp_port_link_mode[i].mask;
1287        }
1288        return ptys_proto;
1289}
1290
1291static u32 mlxsw_sp_to_ptys_speed(u32 speed)
1292{
1293        u32 ptys_proto = 0;
1294        int i;
1295
1296        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1297                if (speed == mlxsw_sp_port_link_mode[i].speed)
1298                        ptys_proto |= mlxsw_sp_port_link_mode[i].mask;
1299        }
1300        return ptys_proto;
1301}
1302
1303static u32 mlxsw_sp_to_ptys_upper_speed(u32 upper_speed)
1304{
1305        u32 ptys_proto = 0;
1306        int i;
1307
1308        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1309                if (mlxsw_sp_port_link_mode[i].speed <= upper_speed)
1310                        ptys_proto |= mlxsw_sp_port_link_mode[i].mask;
1311        }
1312        return ptys_proto;
1313}
1314
1315static int mlxsw_sp_port_set_settings(struct net_device *dev,
1316                                      struct ethtool_cmd *cmd)
1317{
1318        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1319        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1320        char ptys_pl[MLXSW_REG_PTYS_LEN];
1321        u32 speed;
1322        u32 eth_proto_new;
1323        u32 eth_proto_cap;
1324        u32 eth_proto_admin;
1325        bool is_up;
1326        int err;
1327
1328        speed = ethtool_cmd_speed(cmd);
1329
1330        eth_proto_new = cmd->autoneg == AUTONEG_ENABLE ?
1331                mlxsw_sp_to_ptys_advert_link(cmd->advertising) :
1332                mlxsw_sp_to_ptys_speed(speed);
1333
1334        mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port, 0);
1335        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
1336        if (err) {
1337                netdev_err(dev, "Failed to get proto");
1338                return err;
1339        }
1340        mlxsw_reg_ptys_unpack(ptys_pl, &eth_proto_cap, &eth_proto_admin, NULL);
1341
1342        eth_proto_new = eth_proto_new & eth_proto_cap;
1343        if (!eth_proto_new) {
1344                netdev_err(dev, "Not supported proto admin requested");
1345                return -EINVAL;
1346        }
1347        if (eth_proto_new == eth_proto_admin)
1348                return 0;
1349
1350        mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port, eth_proto_new);
1351        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
1352        if (err) {
1353                netdev_err(dev, "Failed to set proto admin");
1354                return err;
1355        }
1356
1357        err = mlxsw_sp_port_oper_status_get(mlxsw_sp_port, &is_up);
1358        if (err) {
1359                netdev_err(dev, "Failed to get oper status");
1360                return err;
1361        }
1362        if (!is_up)
1363                return 0;
1364
1365        err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
1366        if (err) {
1367                netdev_err(dev, "Failed to set admin status");
1368                return err;
1369        }
1370
1371        err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
1372        if (err) {
1373                netdev_err(dev, "Failed to set admin status");
1374                return err;
1375        }
1376
1377        return 0;
1378}
1379
1380static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
1381        .get_drvinfo            = mlxsw_sp_port_get_drvinfo,
1382        .get_link               = ethtool_op_get_link,
1383        .get_strings            = mlxsw_sp_port_get_strings,
1384        .set_phys_id            = mlxsw_sp_port_set_phys_id,
1385        .get_ethtool_stats      = mlxsw_sp_port_get_stats,
1386        .get_sset_count         = mlxsw_sp_port_get_sset_count,
1387        .get_settings           = mlxsw_sp_port_get_settings,
1388        .set_settings           = mlxsw_sp_port_set_settings,
1389};
1390
1391static int
1392mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 width)
1393{
1394        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1395        u32 upper_speed = MLXSW_SP_PORT_BASE_SPEED * width;
1396        char ptys_pl[MLXSW_REG_PTYS_LEN];
1397        u32 eth_proto_admin;
1398
1399        eth_proto_admin = mlxsw_sp_to_ptys_upper_speed(upper_speed);
1400        mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port,
1401                            eth_proto_admin);
1402        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
1403}
1404
1405static int __mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
1406                                  bool split, u8 module, u8 width)
1407{
1408        struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1409        struct mlxsw_sp_port *mlxsw_sp_port;
1410        struct devlink_port *devlink_port;
1411        struct net_device *dev;
1412        size_t bytes;
1413        int err;
1414
1415        dev = alloc_etherdev(sizeof(struct mlxsw_sp_port));
1416        if (!dev)
1417                return -ENOMEM;
1418        mlxsw_sp_port = netdev_priv(dev);
1419        mlxsw_sp_port->dev = dev;
1420        mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
1421        mlxsw_sp_port->local_port = local_port;
1422        mlxsw_sp_port->split = split;
1423        bytes = DIV_ROUND_UP(VLAN_N_VID, BITS_PER_BYTE);
1424        mlxsw_sp_port->active_vlans = kzalloc(bytes, GFP_KERNEL);
1425        if (!mlxsw_sp_port->active_vlans) {
1426                err = -ENOMEM;
1427                goto err_port_active_vlans_alloc;
1428        }
1429        mlxsw_sp_port->untagged_vlans = kzalloc(bytes, GFP_KERNEL);
1430        if (!mlxsw_sp_port->untagged_vlans) {
1431                err = -ENOMEM;
1432                goto err_port_untagged_vlans_alloc;
1433        }
1434        INIT_LIST_HEAD(&mlxsw_sp_port->vports_list);
1435
1436        mlxsw_sp_port->pcpu_stats =
1437                netdev_alloc_pcpu_stats(struct mlxsw_sp_port_pcpu_stats);
1438        if (!mlxsw_sp_port->pcpu_stats) {
1439                err = -ENOMEM;
1440                goto err_alloc_stats;
1441        }
1442
1443        dev->netdev_ops = &mlxsw_sp_port_netdev_ops;
1444        dev->ethtool_ops = &mlxsw_sp_port_ethtool_ops;
1445
1446        err = mlxsw_sp_port_dev_addr_init(mlxsw_sp_port);
1447        if (err) {
1448                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unable to init port mac address\n",
1449                        mlxsw_sp_port->local_port);
1450                goto err_dev_addr_init;
1451        }
1452
1453        netif_carrier_off(dev);
1454
1455        dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_LLTX | NETIF_F_SG |
1456                         NETIF_F_HW_VLAN_CTAG_FILTER;
1457
1458        /* Each packet needs to have a Tx header (metadata) on top all other
1459         * headers.
1460         */
1461        dev->hard_header_len += MLXSW_TXHDR_LEN;
1462
1463        devlink_port = &mlxsw_sp_port->devlink_port;
1464        if (mlxsw_sp_port->split)
1465                devlink_port_split_set(devlink_port, module);
1466        err = devlink_port_register(devlink, devlink_port, local_port);
1467        if (err) {
1468                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to register devlink port\n",
1469                        mlxsw_sp_port->local_port);
1470                goto err_devlink_port_register;
1471        }
1472
1473        err = mlxsw_sp_port_system_port_mapping_set(mlxsw_sp_port);
1474        if (err) {
1475                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set system port mapping\n",
1476                        mlxsw_sp_port->local_port);
1477                goto err_port_system_port_mapping_set;
1478        }
1479
1480        err = mlxsw_sp_port_swid_set(mlxsw_sp_port, 0);
1481        if (err) {
1482                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set SWID\n",
1483                        mlxsw_sp_port->local_port);
1484                goto err_port_swid_set;
1485        }
1486
1487        err = mlxsw_sp_port_speed_by_width_set(mlxsw_sp_port, width);
1488        if (err) {
1489                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to enable speeds\n",
1490                        mlxsw_sp_port->local_port);
1491                goto err_port_speed_by_width_set;
1492        }
1493
1494        err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, ETH_DATA_LEN);
1495        if (err) {
1496                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set MTU\n",
1497                        mlxsw_sp_port->local_port);
1498                goto err_port_mtu_set;
1499        }
1500
1501        err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
1502        if (err)
1503                goto err_port_admin_status_set;
1504
1505        err = mlxsw_sp_port_buffers_init(mlxsw_sp_port);
1506        if (err) {
1507                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize buffers\n",
1508                        mlxsw_sp_port->local_port);
1509                goto err_port_buffers_init;
1510        }
1511
1512        mlxsw_sp_port_switchdev_init(mlxsw_sp_port);
1513        err = register_netdev(dev);
1514        if (err) {
1515                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to register netdev\n",
1516                        mlxsw_sp_port->local_port);
1517                goto err_register_netdev;
1518        }
1519
1520        devlink_port_type_eth_set(devlink_port, dev);
1521
1522        err = mlxsw_sp_port_vlan_init(mlxsw_sp_port);
1523        if (err)
1524                goto err_port_vlan_init;
1525
1526        mlxsw_sp->ports[local_port] = mlxsw_sp_port;
1527        return 0;
1528
1529err_port_vlan_init:
1530        unregister_netdev(dev);
1531err_register_netdev:
1532err_port_buffers_init:
1533err_port_admin_status_set:
1534err_port_mtu_set:
1535err_port_speed_by_width_set:
1536err_port_swid_set:
1537err_port_system_port_mapping_set:
1538        devlink_port_unregister(&mlxsw_sp_port->devlink_port);
1539err_devlink_port_register:
1540err_dev_addr_init:
1541        free_percpu(mlxsw_sp_port->pcpu_stats);
1542err_alloc_stats:
1543        kfree(mlxsw_sp_port->untagged_vlans);
1544err_port_untagged_vlans_alloc:
1545        kfree(mlxsw_sp_port->active_vlans);
1546err_port_active_vlans_alloc:
1547        free_netdev(dev);
1548        return err;
1549}
1550
1551static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
1552                                bool split, u8 module, u8 width, u8 lane)
1553{
1554        int err;
1555
1556        err = mlxsw_sp_port_module_map(mlxsw_sp, local_port, module, width,
1557                                       lane);
1558        if (err)
1559                return err;
1560
1561        err = __mlxsw_sp_port_create(mlxsw_sp, local_port, split, module,
1562                                     width);
1563        if (err)
1564                goto err_port_create;
1565
1566        return 0;
1567
1568err_port_create:
1569        mlxsw_sp_port_module_unmap(mlxsw_sp, local_port);
1570        return err;
1571}
1572
1573static void mlxsw_sp_port_vports_fini(struct mlxsw_sp_port *mlxsw_sp_port)
1574{
1575        struct net_device *dev = mlxsw_sp_port->dev;
1576        struct mlxsw_sp_port *mlxsw_sp_vport, *tmp;
1577
1578        list_for_each_entry_safe(mlxsw_sp_vport, tmp,
1579                                 &mlxsw_sp_port->vports_list, vport.list) {
1580                u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
1581
1582                /* vPorts created for VLAN devices should already be gone
1583                 * by now, since we unregistered the port netdev.
1584                 */
1585                WARN_ON(is_vlan_dev(mlxsw_sp_vport->dev));
1586                mlxsw_sp_port_kill_vid(dev, 0, vid);
1587        }
1588}
1589
1590static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
1591{
1592        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
1593        struct devlink_port *devlink_port;
1594
1595        if (!mlxsw_sp_port)
1596                return;
1597        mlxsw_sp->ports[local_port] = NULL;
1598        devlink_port = &mlxsw_sp_port->devlink_port;
1599        devlink_port_type_clear(devlink_port);
1600        unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
1601        devlink_port_unregister(devlink_port);
1602        mlxsw_sp_port_vports_fini(mlxsw_sp_port);
1603        mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
1604        mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
1605        mlxsw_sp_port_module_unmap(mlxsw_sp, mlxsw_sp_port->local_port);
1606        free_percpu(mlxsw_sp_port->pcpu_stats);
1607        kfree(mlxsw_sp_port->untagged_vlans);
1608        kfree(mlxsw_sp_port->active_vlans);
1609        free_netdev(mlxsw_sp_port->dev);
1610}
1611
1612static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
1613{
1614        int i;
1615
1616        for (i = 1; i < MLXSW_PORT_MAX_PORTS; i++)
1617                mlxsw_sp_port_remove(mlxsw_sp, i);
1618        kfree(mlxsw_sp->ports);
1619}
1620
1621static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
1622{
1623        size_t alloc_size;
1624        u8 module, width;
1625        int i;
1626        int err;
1627
1628        alloc_size = sizeof(struct mlxsw_sp_port *) * MLXSW_PORT_MAX_PORTS;
1629        mlxsw_sp->ports = kzalloc(alloc_size, GFP_KERNEL);
1630        if (!mlxsw_sp->ports)
1631                return -ENOMEM;
1632
1633        for (i = 1; i < MLXSW_PORT_MAX_PORTS; i++) {
1634                err = mlxsw_sp_port_module_info_get(mlxsw_sp, i, &module,
1635                                                    &width);
1636                if (err)
1637                        goto err_port_module_info_get;
1638                if (!width)
1639                        continue;
1640                mlxsw_sp->port_to_module[i] = module;
1641                err = __mlxsw_sp_port_create(mlxsw_sp, i, false, module, width);
1642                if (err)
1643                        goto err_port_create;
1644        }
1645        return 0;
1646
1647err_port_create:
1648err_port_module_info_get:
1649        for (i--; i >= 1; i--)
1650                mlxsw_sp_port_remove(mlxsw_sp, i);
1651        kfree(mlxsw_sp->ports);
1652        return err;
1653}
1654
1655static u8 mlxsw_sp_cluster_base_port_get(u8 local_port)
1656{
1657        u8 offset = (local_port - 1) % MLXSW_SP_PORTS_PER_CLUSTER_MAX;
1658
1659        return local_port - offset;
1660}
1661
1662static int mlxsw_sp_port_split(void *priv, u8 local_port, unsigned int count)
1663{
1664        struct mlxsw_sp *mlxsw_sp = priv;
1665        struct mlxsw_sp_port *mlxsw_sp_port;
1666        u8 width = MLXSW_PORT_MODULE_MAX_WIDTH / count;
1667        u8 module, cur_width, base_port;
1668        int i;
1669        int err;
1670
1671        mlxsw_sp_port = mlxsw_sp->ports[local_port];
1672        if (!mlxsw_sp_port) {
1673                dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
1674                        local_port);
1675                return -EINVAL;
1676        }
1677
1678        if (count != 2 && count != 4) {
1679                netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n");
1680                return -EINVAL;
1681        }
1682
1683        err = mlxsw_sp_port_module_info_get(mlxsw_sp, local_port, &module,
1684                                            &cur_width);
1685        if (err) {
1686                netdev_err(mlxsw_sp_port->dev, "Failed to get port's width\n");
1687                return err;
1688        }
1689
1690        if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) {
1691                netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
1692                return -EINVAL;
1693        }
1694
1695        /* Make sure we have enough slave (even) ports for the split. */
1696        if (count == 2) {
1697                base_port = local_port;
1698                if (mlxsw_sp->ports[base_port + 1]) {
1699                        netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
1700                        return -EINVAL;
1701                }
1702        } else {
1703                base_port = mlxsw_sp_cluster_base_port_get(local_port);
1704                if (mlxsw_sp->ports[base_port + 1] ||
1705                    mlxsw_sp->ports[base_port + 3]) {
1706                        netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
1707                        return -EINVAL;
1708                }
1709        }
1710
1711        for (i = 0; i < count; i++)
1712                mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
1713
1714        for (i = 0; i < count; i++) {
1715                err = mlxsw_sp_port_create(mlxsw_sp, base_port + i, true,
1716                                           module, width, i * width);
1717                if (err) {
1718                        dev_err(mlxsw_sp->bus_info->dev, "Failed to create split port\n");
1719                        goto err_port_create;
1720                }
1721        }
1722
1723        return 0;
1724
1725err_port_create:
1726        for (i--; i >= 0; i--)
1727                mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
1728        for (i = 0; i < count / 2; i++) {
1729                module = mlxsw_sp->port_to_module[base_port + i * 2];
1730                mlxsw_sp_port_create(mlxsw_sp, base_port + i * 2, false,
1731                                     module, MLXSW_PORT_MODULE_MAX_WIDTH, 0);
1732        }
1733        return err;
1734}
1735
1736static int mlxsw_sp_port_unsplit(void *priv, u8 local_port)
1737{
1738        struct mlxsw_sp *mlxsw_sp = priv;
1739        struct mlxsw_sp_port *mlxsw_sp_port;
1740        u8 module, cur_width, base_port;
1741        unsigned int count;
1742        int i;
1743        int err;
1744
1745        mlxsw_sp_port = mlxsw_sp->ports[local_port];
1746        if (!mlxsw_sp_port) {
1747                dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
1748                        local_port);
1749                return -EINVAL;
1750        }
1751
1752        if (!mlxsw_sp_port->split) {
1753                netdev_err(mlxsw_sp_port->dev, "Port wasn't split\n");
1754                return -EINVAL;
1755        }
1756
1757        err = mlxsw_sp_port_module_info_get(mlxsw_sp, local_port, &module,
1758                                            &cur_width);
1759        if (err) {
1760                netdev_err(mlxsw_sp_port->dev, "Failed to get port's width\n");
1761                return err;
1762        }
1763        count = cur_width == 1 ? 4 : 2;
1764
1765        base_port = mlxsw_sp_cluster_base_port_get(local_port);
1766
1767        /* Determine which ports to remove. */
1768        if (count == 2 && local_port >= base_port + 2)
1769                base_port = base_port + 2;
1770
1771        for (i = 0; i < count; i++)
1772                mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
1773
1774        for (i = 0; i < count / 2; i++) {
1775                module = mlxsw_sp->port_to_module[base_port + i * 2];
1776                err = mlxsw_sp_port_create(mlxsw_sp, base_port + i * 2, false,
1777                                           module, MLXSW_PORT_MODULE_MAX_WIDTH,
1778                                           0);
1779                if (err)
1780                        dev_err(mlxsw_sp->bus_info->dev, "Failed to reinstantiate port\n");
1781        }
1782
1783        return 0;
1784}
1785
1786static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
1787                                     char *pude_pl, void *priv)
1788{
1789        struct mlxsw_sp *mlxsw_sp = priv;
1790        struct mlxsw_sp_port *mlxsw_sp_port;
1791        enum mlxsw_reg_pude_oper_status status;
1792        u8 local_port;
1793
1794        local_port = mlxsw_reg_pude_local_port_get(pude_pl);
1795        mlxsw_sp_port = mlxsw_sp->ports[local_port];
1796        if (!mlxsw_sp_port) {
1797                dev_warn(mlxsw_sp->bus_info->dev, "Port %d: Link event received for non-existent port\n",
1798                         local_port);
1799                return;
1800        }
1801
1802        status = mlxsw_reg_pude_oper_status_get(pude_pl);
1803        if (status == MLXSW_PORT_OPER_STATUS_UP) {
1804                netdev_info(mlxsw_sp_port->dev, "link up\n");
1805                netif_carrier_on(mlxsw_sp_port->dev);
1806        } else {
1807                netdev_info(mlxsw_sp_port->dev, "link down\n");
1808                netif_carrier_off(mlxsw_sp_port->dev);
1809        }
1810}
1811
1812static struct mlxsw_event_listener mlxsw_sp_pude_event = {
1813        .func = mlxsw_sp_pude_event_func,
1814        .trap_id = MLXSW_TRAP_ID_PUDE,
1815};
1816
1817static int mlxsw_sp_event_register(struct mlxsw_sp *mlxsw_sp,
1818                                   enum mlxsw_event_trap_id trap_id)
1819{
1820        struct mlxsw_event_listener *el;
1821        char hpkt_pl[MLXSW_REG_HPKT_LEN];
1822        int err;
1823
1824        switch (trap_id) {
1825        case MLXSW_TRAP_ID_PUDE:
1826                el = &mlxsw_sp_pude_event;
1827                break;
1828        }
1829        err = mlxsw_core_event_listener_register(mlxsw_sp->core, el, mlxsw_sp);
1830        if (err)
1831                return err;
1832
1833        mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, trap_id);
1834        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
1835        if (err)
1836                goto err_event_trap_set;
1837
1838        return 0;
1839
1840err_event_trap_set:
1841        mlxsw_core_event_listener_unregister(mlxsw_sp->core, el, mlxsw_sp);
1842        return err;
1843}
1844
1845static void mlxsw_sp_event_unregister(struct mlxsw_sp *mlxsw_sp,
1846                                      enum mlxsw_event_trap_id trap_id)
1847{
1848        struct mlxsw_event_listener *el;
1849
1850        switch (trap_id) {
1851        case MLXSW_TRAP_ID_PUDE:
1852                el = &mlxsw_sp_pude_event;
1853                break;
1854        }
1855        mlxsw_core_event_listener_unregister(mlxsw_sp->core, el, mlxsw_sp);
1856}
1857
1858static void mlxsw_sp_rx_listener_func(struct sk_buff *skb, u8 local_port,
1859                                      void *priv)
1860{
1861        struct mlxsw_sp *mlxsw_sp = priv;
1862        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
1863        struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
1864
1865        if (unlikely(!mlxsw_sp_port)) {
1866                dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n",
1867                                     local_port);
1868                return;
1869        }
1870
1871        skb->dev = mlxsw_sp_port->dev;
1872
1873        pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
1874        u64_stats_update_begin(&pcpu_stats->syncp);
1875        pcpu_stats->rx_packets++;
1876        pcpu_stats->rx_bytes += skb->len;
1877        u64_stats_update_end(&pcpu_stats->syncp);
1878
1879        skb->protocol = eth_type_trans(skb, skb->dev);
1880        netif_receive_skb(skb);
1881}
1882
1883static const struct mlxsw_rx_listener mlxsw_sp_rx_listener[] = {
1884        {
1885                .func = mlxsw_sp_rx_listener_func,
1886                .local_port = MLXSW_PORT_DONT_CARE,
1887                .trap_id = MLXSW_TRAP_ID_FDB_MC,
1888        },
1889        /* Traps for specific L2 packet types, not trapped as FDB MC */
1890        {
1891                .func = mlxsw_sp_rx_listener_func,
1892                .local_port = MLXSW_PORT_DONT_CARE,
1893                .trap_id = MLXSW_TRAP_ID_STP,
1894        },
1895        {
1896                .func = mlxsw_sp_rx_listener_func,
1897                .local_port = MLXSW_PORT_DONT_CARE,
1898                .trap_id = MLXSW_TRAP_ID_LACP,
1899        },
1900        {
1901                .func = mlxsw_sp_rx_listener_func,
1902                .local_port = MLXSW_PORT_DONT_CARE,
1903                .trap_id = MLXSW_TRAP_ID_EAPOL,
1904        },
1905        {
1906                .func = mlxsw_sp_rx_listener_func,
1907                .local_port = MLXSW_PORT_DONT_CARE,
1908                .trap_id = MLXSW_TRAP_ID_LLDP,
1909        },
1910        {
1911                .func = mlxsw_sp_rx_listener_func,
1912                .local_port = MLXSW_PORT_DONT_CARE,
1913                .trap_id = MLXSW_TRAP_ID_MMRP,
1914        },
1915        {
1916                .func = mlxsw_sp_rx_listener_func,
1917                .local_port = MLXSW_PORT_DONT_CARE,
1918                .trap_id = MLXSW_TRAP_ID_MVRP,
1919        },
1920        {
1921                .func = mlxsw_sp_rx_listener_func,
1922                .local_port = MLXSW_PORT_DONT_CARE,
1923                .trap_id = MLXSW_TRAP_ID_RPVST,
1924        },
1925        {
1926                .func = mlxsw_sp_rx_listener_func,
1927                .local_port = MLXSW_PORT_DONT_CARE,
1928                .trap_id = MLXSW_TRAP_ID_DHCP,
1929        },
1930        {
1931                .func = mlxsw_sp_rx_listener_func,
1932                .local_port = MLXSW_PORT_DONT_CARE,
1933                .trap_id = MLXSW_TRAP_ID_IGMP_QUERY,
1934        },
1935        {
1936                .func = mlxsw_sp_rx_listener_func,
1937                .local_port = MLXSW_PORT_DONT_CARE,
1938                .trap_id = MLXSW_TRAP_ID_IGMP_V1_REPORT,
1939        },
1940        {
1941                .func = mlxsw_sp_rx_listener_func,
1942                .local_port = MLXSW_PORT_DONT_CARE,
1943                .trap_id = MLXSW_TRAP_ID_IGMP_V2_REPORT,
1944        },
1945        {
1946                .func = mlxsw_sp_rx_listener_func,
1947                .local_port = MLXSW_PORT_DONT_CARE,
1948                .trap_id = MLXSW_TRAP_ID_IGMP_V2_LEAVE,
1949        },
1950        {
1951                .func = mlxsw_sp_rx_listener_func,
1952                .local_port = MLXSW_PORT_DONT_CARE,
1953                .trap_id = MLXSW_TRAP_ID_IGMP_V3_REPORT,
1954        },
1955};
1956
1957static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
1958{
1959        char htgt_pl[MLXSW_REG_HTGT_LEN];
1960        char hpkt_pl[MLXSW_REG_HPKT_LEN];
1961        int i;
1962        int err;
1963
1964        mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_RX);
1965        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl);
1966        if (err)
1967                return err;
1968
1969        mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_CTRL);
1970        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl);
1971        if (err)
1972                return err;
1973
1974        for (i = 0; i < ARRAY_SIZE(mlxsw_sp_rx_listener); i++) {
1975                err = mlxsw_core_rx_listener_register(mlxsw_sp->core,
1976                                                      &mlxsw_sp_rx_listener[i],
1977                                                      mlxsw_sp);
1978                if (err)
1979                        goto err_rx_listener_register;
1980
1981                mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,
1982                                    mlxsw_sp_rx_listener[i].trap_id);
1983                err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
1984                if (err)
1985                        goto err_rx_trap_set;
1986        }
1987        return 0;
1988
1989err_rx_trap_set:
1990        mlxsw_core_rx_listener_unregister(mlxsw_sp->core,
1991                                          &mlxsw_sp_rx_listener[i],
1992                                          mlxsw_sp);
1993err_rx_listener_register:
1994        for (i--; i >= 0; i--) {
1995                mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD,
1996                                    mlxsw_sp_rx_listener[i].trap_id);
1997                mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
1998
1999                mlxsw_core_rx_listener_unregister(mlxsw_sp->core,
2000                                                  &mlxsw_sp_rx_listener[i],
2001                                                  mlxsw_sp);
2002        }
2003        return err;
2004}
2005
2006static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
2007{
2008        char hpkt_pl[MLXSW_REG_HPKT_LEN];
2009        int i;
2010
2011        for (i = 0; i < ARRAY_SIZE(mlxsw_sp_rx_listener); i++) {
2012                mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD,
2013                                    mlxsw_sp_rx_listener[i].trap_id);
2014                mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
2015
2016                mlxsw_core_rx_listener_unregister(mlxsw_sp->core,
2017                                                  &mlxsw_sp_rx_listener[i],
2018                                                  mlxsw_sp);
2019        }
2020}
2021
2022static int __mlxsw_sp_flood_init(struct mlxsw_core *mlxsw_core,
2023                                 enum mlxsw_reg_sfgc_type type,
2024                                 enum mlxsw_reg_sfgc_bridge_type bridge_type)
2025{
2026        enum mlxsw_flood_table_type table_type;
2027        enum mlxsw_sp_flood_table flood_table;
2028        char sfgc_pl[MLXSW_REG_SFGC_LEN];
2029
2030        if (bridge_type == MLXSW_REG_SFGC_BRIDGE_TYPE_VFID)
2031                table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID;
2032        else
2033                table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFEST;
2034
2035        if (type == MLXSW_REG_SFGC_TYPE_UNKNOWN_UNICAST)
2036                flood_table = MLXSW_SP_FLOOD_TABLE_UC;
2037        else
2038                flood_table = MLXSW_SP_FLOOD_TABLE_BM;
2039
2040        mlxsw_reg_sfgc_pack(sfgc_pl, type, bridge_type, table_type,
2041                            flood_table);
2042        return mlxsw_reg_write(mlxsw_core, MLXSW_REG(sfgc), sfgc_pl);
2043}
2044
2045static int mlxsw_sp_flood_init(struct mlxsw_sp *mlxsw_sp)
2046{
2047        int type, err;
2048
2049        for (type = 0; type < MLXSW_REG_SFGC_TYPE_MAX; type++) {
2050                if (type == MLXSW_REG_SFGC_TYPE_RESERVED)
2051                        continue;
2052
2053                err = __mlxsw_sp_flood_init(mlxsw_sp->core, type,
2054                                            MLXSW_REG_SFGC_BRIDGE_TYPE_VFID);
2055                if (err)
2056                        return err;
2057
2058                err = __mlxsw_sp_flood_init(mlxsw_sp->core, type,
2059                                            MLXSW_REG_SFGC_BRIDGE_TYPE_1Q_FID);
2060                if (err)
2061                        return err;
2062        }
2063
2064        return 0;
2065}
2066
2067static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
2068{
2069        char slcr_pl[MLXSW_REG_SLCR_LEN];
2070
2071        mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
2072                                     MLXSW_REG_SLCR_LAG_HASH_DMAC |
2073                                     MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
2074                                     MLXSW_REG_SLCR_LAG_HASH_VLANID |
2075                                     MLXSW_REG_SLCR_LAG_HASH_SIP |
2076                                     MLXSW_REG_SLCR_LAG_HASH_DIP |
2077                                     MLXSW_REG_SLCR_LAG_HASH_SPORT |
2078                                     MLXSW_REG_SLCR_LAG_HASH_DPORT |
2079                                     MLXSW_REG_SLCR_LAG_HASH_IPPROTO);
2080        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcr), slcr_pl);
2081}
2082
2083static int mlxsw_sp_init(void *priv, struct mlxsw_core *mlxsw_core,
2084                         const struct mlxsw_bus_info *mlxsw_bus_info)
2085{
2086        struct mlxsw_sp *mlxsw_sp = priv;
2087        int err;
2088
2089        mlxsw_sp->core = mlxsw_core;
2090        mlxsw_sp->bus_info = mlxsw_bus_info;
2091        INIT_LIST_HEAD(&mlxsw_sp->port_vfids.list);
2092        INIT_LIST_HEAD(&mlxsw_sp->br_vfids.list);
2093        INIT_LIST_HEAD(&mlxsw_sp->br_mids.list);
2094
2095        err = mlxsw_sp_base_mac_get(mlxsw_sp);
2096        if (err) {
2097                dev_err(mlxsw_sp->bus_info->dev, "Failed to get base mac\n");
2098                return err;
2099        }
2100
2101        err = mlxsw_sp_ports_create(mlxsw_sp);
2102        if (err) {
2103                dev_err(mlxsw_sp->bus_info->dev, "Failed to create ports\n");
2104                return err;
2105        }
2106
2107        err = mlxsw_sp_event_register(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
2108        if (err) {
2109                dev_err(mlxsw_sp->bus_info->dev, "Failed to register for PUDE events\n");
2110                goto err_event_register;
2111        }
2112
2113        err = mlxsw_sp_traps_init(mlxsw_sp);
2114        if (err) {
2115                dev_err(mlxsw_sp->bus_info->dev, "Failed to set traps for RX\n");
2116                goto err_rx_listener_register;
2117        }
2118
2119        err = mlxsw_sp_flood_init(mlxsw_sp);
2120        if (err) {
2121                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize flood tables\n");
2122                goto err_flood_init;
2123        }
2124
2125        err = mlxsw_sp_buffers_init(mlxsw_sp);
2126        if (err) {
2127                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize buffers\n");
2128                goto err_buffers_init;
2129        }
2130
2131        err = mlxsw_sp_lag_init(mlxsw_sp);
2132        if (err) {
2133                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize LAG\n");
2134                goto err_lag_init;
2135        }
2136
2137        err = mlxsw_sp_switchdev_init(mlxsw_sp);
2138        if (err) {
2139                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize switchdev\n");
2140                goto err_switchdev_init;
2141        }
2142
2143        return 0;
2144
2145err_switchdev_init:
2146err_lag_init:
2147err_buffers_init:
2148err_flood_init:
2149        mlxsw_sp_traps_fini(mlxsw_sp);
2150err_rx_listener_register:
2151        mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
2152err_event_register:
2153        mlxsw_sp_ports_remove(mlxsw_sp);
2154        return err;
2155}
2156
2157static void mlxsw_sp_fini(void *priv)
2158{
2159        struct mlxsw_sp *mlxsw_sp = priv;
2160
2161        mlxsw_sp_switchdev_fini(mlxsw_sp);
2162        mlxsw_sp_traps_fini(mlxsw_sp);
2163        mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
2164        mlxsw_sp_ports_remove(mlxsw_sp);
2165}
2166
2167static struct mlxsw_config_profile mlxsw_sp_config_profile = {
2168        .used_max_vepa_channels         = 1,
2169        .max_vepa_channels              = 0,
2170        .used_max_lag                   = 1,
2171        .max_lag                        = MLXSW_SP_LAG_MAX,
2172        .used_max_port_per_lag          = 1,
2173        .max_port_per_lag               = MLXSW_SP_PORT_PER_LAG_MAX,
2174        .used_max_mid                   = 1,
2175        .max_mid                        = MLXSW_SP_MID_MAX,
2176        .used_max_pgt                   = 1,
2177        .max_pgt                        = 0,
2178        .used_max_system_port           = 1,
2179        .max_system_port                = 64,
2180        .used_max_vlan_groups           = 1,
2181        .max_vlan_groups                = 127,
2182        .used_max_regions               = 1,
2183        .max_regions                    = 400,
2184        .used_flood_tables              = 1,
2185        .used_flood_mode                = 1,
2186        .flood_mode                     = 3,
2187        .max_fid_offset_flood_tables    = 2,
2188        .fid_offset_flood_table_size    = VLAN_N_VID - 1,
2189        .max_fid_flood_tables           = 2,
2190        .fid_flood_table_size           = MLXSW_SP_VFID_MAX,
2191        .used_max_ib_mc                 = 1,
2192        .max_ib_mc                      = 0,
2193        .used_max_pkey                  = 1,
2194        .max_pkey                       = 0,
2195        .swid_config                    = {
2196                {
2197                        .used_type      = 1,
2198                        .type           = MLXSW_PORT_SWID_TYPE_ETH,
2199                }
2200        },
2201};
2202
2203static struct mlxsw_driver mlxsw_sp_driver = {
2204        .kind                   = MLXSW_DEVICE_KIND_SPECTRUM,
2205        .owner                  = THIS_MODULE,
2206        .priv_size              = sizeof(struct mlxsw_sp),
2207        .init                   = mlxsw_sp_init,
2208        .fini                   = mlxsw_sp_fini,
2209        .port_split             = mlxsw_sp_port_split,
2210        .port_unsplit           = mlxsw_sp_port_unsplit,
2211        .txhdr_construct        = mlxsw_sp_txhdr_construct,
2212        .txhdr_len              = MLXSW_TXHDR_LEN,
2213        .profile                = &mlxsw_sp_config_profile,
2214};
2215
2216static int
2217mlxsw_sp_port_fdb_flush_by_port(const struct mlxsw_sp_port *mlxsw_sp_port)
2218{
2219        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2220        char sfdf_pl[MLXSW_REG_SFDF_LEN];
2221
2222        mlxsw_reg_sfdf_pack(sfdf_pl, MLXSW_REG_SFDF_FLUSH_PER_PORT);
2223        mlxsw_reg_sfdf_system_port_set(sfdf_pl, mlxsw_sp_port->local_port);
2224
2225        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdf), sfdf_pl);
2226}
2227
2228static int
2229mlxsw_sp_port_fdb_flush_by_port_fid(const struct mlxsw_sp_port *mlxsw_sp_port,
2230                                    u16 fid)
2231{
2232        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2233        char sfdf_pl[MLXSW_REG_SFDF_LEN];
2234
2235        mlxsw_reg_sfdf_pack(sfdf_pl, MLXSW_REG_SFDF_FLUSH_PER_PORT_AND_FID);
2236        mlxsw_reg_sfdf_fid_set(sfdf_pl, fid);
2237        mlxsw_reg_sfdf_port_fid_system_port_set(sfdf_pl,
2238                                                mlxsw_sp_port->local_port);
2239
2240        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdf), sfdf_pl);
2241}
2242
2243static int
2244mlxsw_sp_port_fdb_flush_by_lag_id(const struct mlxsw_sp_port *mlxsw_sp_port)
2245{
2246        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2247        char sfdf_pl[MLXSW_REG_SFDF_LEN];
2248
2249        mlxsw_reg_sfdf_pack(sfdf_pl, MLXSW_REG_SFDF_FLUSH_PER_LAG);
2250        mlxsw_reg_sfdf_lag_id_set(sfdf_pl, mlxsw_sp_port->lag_id);
2251
2252        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdf), sfdf_pl);
2253}
2254
2255static int
2256mlxsw_sp_port_fdb_flush_by_lag_id_fid(const struct mlxsw_sp_port *mlxsw_sp_port,
2257                                      u16 fid)
2258{
2259        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2260        char sfdf_pl[MLXSW_REG_SFDF_LEN];
2261
2262        mlxsw_reg_sfdf_pack(sfdf_pl, MLXSW_REG_SFDF_FLUSH_PER_LAG_AND_FID);
2263        mlxsw_reg_sfdf_fid_set(sfdf_pl, fid);
2264        mlxsw_reg_sfdf_lag_fid_lag_id_set(sfdf_pl, mlxsw_sp_port->lag_id);
2265
2266        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdf), sfdf_pl);
2267}
2268
2269static int
2270__mlxsw_sp_port_fdb_flush(const struct mlxsw_sp_port *mlxsw_sp_port)
2271{
2272        int err, last_err = 0;
2273        u16 vid;
2274
2275        for (vid = 1; vid < VLAN_N_VID - 1; vid++) {
2276                err = mlxsw_sp_port_fdb_flush_by_port_fid(mlxsw_sp_port, vid);
2277                if (err)
2278                        last_err = err;
2279        }
2280
2281        return last_err;
2282}
2283
2284static int
2285__mlxsw_sp_port_fdb_flush_lagged(const struct mlxsw_sp_port *mlxsw_sp_port)
2286{
2287        int err, last_err = 0;
2288        u16 vid;
2289
2290        for (vid = 1; vid < VLAN_N_VID - 1; vid++) {
2291                err = mlxsw_sp_port_fdb_flush_by_lag_id_fid(mlxsw_sp_port, vid);
2292                if (err)
2293                        last_err = err;
2294        }
2295
2296        return last_err;
2297}
2298
2299static int mlxsw_sp_port_fdb_flush(struct mlxsw_sp_port *mlxsw_sp_port)
2300{
2301        if (!list_empty(&mlxsw_sp_port->vports_list))
2302                if (mlxsw_sp_port->lagged)
2303                        return __mlxsw_sp_port_fdb_flush_lagged(mlxsw_sp_port);
2304                else
2305                        return __mlxsw_sp_port_fdb_flush(mlxsw_sp_port);
2306        else
2307                if (mlxsw_sp_port->lagged)
2308                        return mlxsw_sp_port_fdb_flush_by_lag_id(mlxsw_sp_port);
2309                else
2310                        return mlxsw_sp_port_fdb_flush_by_port(mlxsw_sp_port);
2311}
2312
2313static int mlxsw_sp_vport_fdb_flush(struct mlxsw_sp_port *mlxsw_sp_vport)
2314{
2315        u16 vfid = mlxsw_sp_vport_vfid_get(mlxsw_sp_vport);
2316        u16 fid = mlxsw_sp_vfid_to_fid(vfid);
2317
2318        if (mlxsw_sp_vport->lagged)
2319                return mlxsw_sp_port_fdb_flush_by_lag_id_fid(mlxsw_sp_vport,
2320                                                             fid);
2321        else
2322                return mlxsw_sp_port_fdb_flush_by_port_fid(mlxsw_sp_vport, fid);
2323}
2324
2325static bool mlxsw_sp_port_dev_check(const struct net_device *dev)
2326{
2327        return dev->netdev_ops == &mlxsw_sp_port_netdev_ops;
2328}
2329
2330static int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port)
2331{
2332        struct net_device *dev = mlxsw_sp_port->dev;
2333        int err;
2334
2335        /* When port is not bridged untagged packets are tagged with
2336         * PVID=VID=1, thereby creating an implicit VLAN interface in
2337         * the device. Remove it and let bridge code take care of its
2338         * own VLANs.
2339         */
2340        err = mlxsw_sp_port_kill_vid(dev, 0, 1);
2341        if (err)
2342                return err;
2343
2344        mlxsw_sp_port->learning = 1;
2345        mlxsw_sp_port->learning_sync = 1;
2346        mlxsw_sp_port->uc_flood = 1;
2347        mlxsw_sp_port->bridged = 1;
2348
2349        return 0;
2350}
2351
2352static int mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port,
2353                                      bool flush_fdb)
2354{
2355        struct net_device *dev = mlxsw_sp_port->dev;
2356
2357        if (flush_fdb && mlxsw_sp_port_fdb_flush(mlxsw_sp_port))
2358                netdev_err(mlxsw_sp_port->dev, "Failed to flush FDB\n");
2359
2360        mlxsw_sp_port_pvid_set(mlxsw_sp_port, 1);
2361
2362        mlxsw_sp_port->learning = 0;
2363        mlxsw_sp_port->learning_sync = 0;
2364        mlxsw_sp_port->uc_flood = 0;
2365        mlxsw_sp_port->bridged = 0;
2366
2367        /* Add implicit VLAN interface in the device, so that untagged
2368         * packets will be classified to the default vFID.
2369         */
2370        return mlxsw_sp_port_add_vid(dev, 0, 1);
2371}
2372
2373static bool mlxsw_sp_master_bridge_check(struct mlxsw_sp *mlxsw_sp,
2374                                         struct net_device *br_dev)
2375{
2376        return !mlxsw_sp->master_bridge.dev ||
2377               mlxsw_sp->master_bridge.dev == br_dev;
2378}
2379
2380static void mlxsw_sp_master_bridge_inc(struct mlxsw_sp *mlxsw_sp,
2381                                       struct net_device *br_dev)
2382{
2383        mlxsw_sp->master_bridge.dev = br_dev;
2384        mlxsw_sp->master_bridge.ref_count++;
2385}
2386
2387static void mlxsw_sp_master_bridge_dec(struct mlxsw_sp *mlxsw_sp,
2388                                       struct net_device *br_dev)
2389{
2390        if (--mlxsw_sp->master_bridge.ref_count == 0)
2391                mlxsw_sp->master_bridge.dev = NULL;
2392}
2393
2394static int mlxsw_sp_lag_create(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
2395{
2396        char sldr_pl[MLXSW_REG_SLDR_LEN];
2397
2398        mlxsw_reg_sldr_lag_create_pack(sldr_pl, lag_id);
2399        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
2400}
2401
2402static int mlxsw_sp_lag_destroy(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
2403{
2404        char sldr_pl[MLXSW_REG_SLDR_LEN];
2405
2406        mlxsw_reg_sldr_lag_destroy_pack(sldr_pl, lag_id);
2407        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
2408}
2409
2410static int mlxsw_sp_lag_col_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
2411                                     u16 lag_id, u8 port_index)
2412{
2413        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2414        char slcor_pl[MLXSW_REG_SLCOR_LEN];
2415
2416        mlxsw_reg_slcor_port_add_pack(slcor_pl, mlxsw_sp_port->local_port,
2417                                      lag_id, port_index);
2418        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
2419}
2420
2421static int mlxsw_sp_lag_col_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
2422                                        u16 lag_id)
2423{
2424        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2425        char slcor_pl[MLXSW_REG_SLCOR_LEN];
2426
2427        mlxsw_reg_slcor_port_remove_pack(slcor_pl, mlxsw_sp_port->local_port,
2428                                         lag_id);
2429        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
2430}
2431
2432static int mlxsw_sp_lag_col_port_enable(struct mlxsw_sp_port *mlxsw_sp_port,
2433                                        u16 lag_id)
2434{
2435        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2436        char slcor_pl[MLXSW_REG_SLCOR_LEN];
2437
2438        mlxsw_reg_slcor_col_enable_pack(slcor_pl, mlxsw_sp_port->local_port,
2439                                        lag_id);
2440        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
2441}
2442
2443static int mlxsw_sp_lag_col_port_disable(struct mlxsw_sp_port *mlxsw_sp_port,
2444                                         u16 lag_id)
2445{
2446        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2447        char slcor_pl[MLXSW_REG_SLCOR_LEN];
2448
2449        mlxsw_reg_slcor_col_disable_pack(slcor_pl, mlxsw_sp_port->local_port,
2450                                         lag_id);
2451        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
2452}
2453
2454static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
2455                                  struct net_device *lag_dev,
2456                                  u16 *p_lag_id)
2457{
2458        struct mlxsw_sp_upper *lag;
2459        int free_lag_id = -1;
2460        int i;
2461
2462        for (i = 0; i < MLXSW_SP_LAG_MAX; i++) {
2463                lag = mlxsw_sp_lag_get(mlxsw_sp, i);
2464                if (lag->ref_count) {
2465                        if (lag->dev == lag_dev) {
2466                                *p_lag_id = i;
2467                                return 0;
2468                        }
2469                } else if (free_lag_id < 0) {
2470                        free_lag_id = i;
2471                }
2472        }
2473        if (free_lag_id < 0)
2474                return -EBUSY;
2475        *p_lag_id = free_lag_id;
2476        return 0;
2477}
2478
2479static bool
2480mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
2481                          struct net_device *lag_dev,
2482                          struct netdev_lag_upper_info *lag_upper_info)
2483{
2484        u16 lag_id;
2485
2486        if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0)
2487                return false;
2488        if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
2489                return false;
2490        return true;
2491}
2492
2493static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp *mlxsw_sp,
2494                                       u16 lag_id, u8 *p_port_index)
2495{
2496        int i;
2497
2498        for (i = 0; i < MLXSW_SP_PORT_PER_LAG_MAX; i++) {
2499                if (!mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i)) {
2500                        *p_port_index = i;
2501                        return 0;
2502                }
2503        }
2504        return -EBUSY;
2505}
2506
2507static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
2508                                  struct net_device *lag_dev)
2509{
2510        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2511        struct mlxsw_sp_upper *lag;
2512        u16 lag_id;
2513        u8 port_index;
2514        int err;
2515
2516        err = mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id);
2517        if (err)
2518                return err;
2519        lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
2520        if (!lag->ref_count) {
2521                err = mlxsw_sp_lag_create(mlxsw_sp, lag_id);
2522                if (err)
2523                        return err;
2524                lag->dev = lag_dev;
2525        }
2526
2527        err = mlxsw_sp_port_lag_index_get(mlxsw_sp, lag_id, &port_index);
2528        if (err)
2529                return err;
2530        err = mlxsw_sp_lag_col_port_add(mlxsw_sp_port, lag_id, port_index);
2531        if (err)
2532                goto err_col_port_add;
2533        err = mlxsw_sp_lag_col_port_enable(mlxsw_sp_port, lag_id);
2534        if (err)
2535                goto err_col_port_enable;
2536
2537        mlxsw_core_lag_mapping_set(mlxsw_sp->core, lag_id, port_index,
2538                                   mlxsw_sp_port->local_port);
2539        mlxsw_sp_port->lag_id = lag_id;
2540        mlxsw_sp_port->lagged = 1;
2541        lag->ref_count++;
2542        return 0;
2543
2544err_col_port_enable:
2545        mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
2546err_col_port_add:
2547        if (!lag->ref_count)
2548                mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
2549        return err;
2550}
2551
2552static int mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport,
2553                                       struct net_device *br_dev,
2554                                       bool flush_fdb);
2555
2556static int mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
2557                                   struct net_device *lag_dev)
2558{
2559        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2560        struct mlxsw_sp_port *mlxsw_sp_vport;
2561        struct mlxsw_sp_upper *lag;
2562        u16 lag_id = mlxsw_sp_port->lag_id;
2563        int err;
2564
2565        if (!mlxsw_sp_port->lagged)
2566                return 0;
2567        lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
2568        WARN_ON(lag->ref_count == 0);
2569
2570        err = mlxsw_sp_lag_col_port_disable(mlxsw_sp_port, lag_id);
2571        if (err)
2572                return err;
2573        err = mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
2574        if (err)
2575                return err;
2576
2577        /* In case we leave a LAG device that has bridges built on top,
2578         * then their teardown sequence is never issued and we need to
2579         * invoke the necessary cleanup routines ourselves.
2580         */
2581        list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list,
2582                            vport.list) {
2583                struct net_device *br_dev;
2584
2585                if (!mlxsw_sp_vport->bridged)
2586                        continue;
2587
2588                br_dev = mlxsw_sp_vport_br_get(mlxsw_sp_vport);
2589                mlxsw_sp_vport_bridge_leave(mlxsw_sp_vport, br_dev, false);
2590        }
2591
2592        if (mlxsw_sp_port->bridged) {
2593                mlxsw_sp_port_active_vlans_del(mlxsw_sp_port);
2594                mlxsw_sp_port_bridge_leave(mlxsw_sp_port, false);
2595                mlxsw_sp_master_bridge_dec(mlxsw_sp, NULL);
2596        }
2597
2598        if (lag->ref_count == 1) {
2599                if (mlxsw_sp_port_fdb_flush_by_lag_id(mlxsw_sp_port))
2600                        netdev_err(mlxsw_sp_port->dev, "Failed to flush FDB\n");
2601                err = mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
2602                if (err)
2603                        return err;
2604        }
2605
2606        mlxsw_core_lag_mapping_clear(mlxsw_sp->core, lag_id,
2607                                     mlxsw_sp_port->local_port);
2608        mlxsw_sp_port->lagged = 0;
2609        lag->ref_count--;
2610        return 0;
2611}
2612
2613static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
2614                                      u16 lag_id)
2615{
2616        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2617        char sldr_pl[MLXSW_REG_SLDR_LEN];
2618
2619        mlxsw_reg_sldr_lag_add_port_pack(sldr_pl, lag_id,
2620                                         mlxsw_sp_port->local_port);
2621        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
2622}
2623
2624static int mlxsw_sp_lag_dist_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
2625                                         u16 lag_id)
2626{
2627        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2628        char sldr_pl[MLXSW_REG_SLDR_LEN];
2629
2630        mlxsw_reg_sldr_lag_remove_port_pack(sldr_pl, lag_id,
2631                                            mlxsw_sp_port->local_port);
2632        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
2633}
2634
2635static int mlxsw_sp_port_lag_tx_en_set(struct mlxsw_sp_port *mlxsw_sp_port,
2636                                       bool lag_tx_enabled)
2637{
2638        if (lag_tx_enabled)
2639                return mlxsw_sp_lag_dist_port_add(mlxsw_sp_port,
2640                                                  mlxsw_sp_port->lag_id);
2641        else
2642                return mlxsw_sp_lag_dist_port_remove(mlxsw_sp_port,
2643                                                     mlxsw_sp_port->lag_id);
2644}
2645
2646static int mlxsw_sp_port_lag_changed(struct mlxsw_sp_port *mlxsw_sp_port,
2647                                     struct netdev_lag_lower_state_info *info)
2648{
2649        return mlxsw_sp_port_lag_tx_en_set(mlxsw_sp_port, info->tx_enabled);
2650}
2651
2652static int mlxsw_sp_port_vlan_link(struct mlxsw_sp_port *mlxsw_sp_port,
2653                                   struct net_device *vlan_dev)
2654{
2655        struct mlxsw_sp_port *mlxsw_sp_vport;
2656        u16 vid = vlan_dev_vlan_id(vlan_dev);
2657
2658        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
2659        if (!mlxsw_sp_vport) {
2660                WARN_ON(!mlxsw_sp_vport);
2661                return -EINVAL;
2662        }
2663
2664        mlxsw_sp_vport->dev = vlan_dev;
2665
2666        return 0;
2667}
2668
2669static int mlxsw_sp_port_vlan_unlink(struct mlxsw_sp_port *mlxsw_sp_port,
2670                                     struct net_device *vlan_dev)
2671{
2672        struct mlxsw_sp_port *mlxsw_sp_vport;
2673        u16 vid = vlan_dev_vlan_id(vlan_dev);
2674
2675        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
2676        if (!mlxsw_sp_vport) {
2677                WARN_ON(!mlxsw_sp_vport);
2678                return -EINVAL;
2679        }
2680
2681        /* When removing a VLAN device while still bridged we should first
2682         * remove it from the bridge, as we receive the bridge's notification
2683         * when the vPort is already gone.
2684         */
2685        if (mlxsw_sp_vport->bridged) {
2686                struct net_device *br_dev;
2687
2688                br_dev = mlxsw_sp_vport_br_get(mlxsw_sp_vport);
2689                mlxsw_sp_vport_bridge_leave(mlxsw_sp_vport, br_dev, true);
2690        }
2691
2692        mlxsw_sp_vport->dev = mlxsw_sp_port->dev;
2693
2694        return 0;
2695}
2696
2697static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
2698                                               unsigned long event, void *ptr)
2699{
2700        struct netdev_notifier_changeupper_info *info;
2701        struct mlxsw_sp_port *mlxsw_sp_port;
2702        struct net_device *upper_dev;
2703        struct mlxsw_sp *mlxsw_sp;
2704        int err;
2705
2706        mlxsw_sp_port = netdev_priv(dev);
2707        mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2708        info = ptr;
2709
2710        switch (event) {
2711        case NETDEV_PRECHANGEUPPER:
2712                upper_dev = info->upper_dev;
2713                if (!info->master || !info->linking)
2714                        break;
2715                /* HW limitation forbids to put ports to multiple bridges. */
2716                if (netif_is_bridge_master(upper_dev) &&
2717                    !mlxsw_sp_master_bridge_check(mlxsw_sp, upper_dev))
2718                        return NOTIFY_BAD;
2719                if (netif_is_lag_master(upper_dev) &&
2720                    !mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
2721                                               info->upper_info))
2722                        return NOTIFY_BAD;
2723                break;
2724        case NETDEV_CHANGEUPPER:
2725                upper_dev = info->upper_dev;
2726                if (is_vlan_dev(upper_dev)) {
2727                        if (info->linking) {
2728                                err = mlxsw_sp_port_vlan_link(mlxsw_sp_port,
2729                                                              upper_dev);
2730                                if (err) {
2731                                        netdev_err(dev, "Failed to link VLAN device\n");
2732                                        return NOTIFY_BAD;
2733                                }
2734                        } else {
2735                                err = mlxsw_sp_port_vlan_unlink(mlxsw_sp_port,
2736                                                                upper_dev);
2737                                if (err) {
2738                                        netdev_err(dev, "Failed to unlink VLAN device\n");
2739                                        return NOTIFY_BAD;
2740                                }
2741                        }
2742                } else if (netif_is_bridge_master(upper_dev)) {
2743                        if (info->linking) {
2744                                err = mlxsw_sp_port_bridge_join(mlxsw_sp_port);
2745                                if (err) {
2746                                        netdev_err(dev, "Failed to join bridge\n");
2747                                        return NOTIFY_BAD;
2748                                }
2749                                mlxsw_sp_master_bridge_inc(mlxsw_sp, upper_dev);
2750                        } else {
2751                                err = mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
2752                                                                 true);
2753                                mlxsw_sp_master_bridge_dec(mlxsw_sp, upper_dev);
2754                                if (err) {
2755                                        netdev_err(dev, "Failed to leave bridge\n");
2756                                        return NOTIFY_BAD;
2757                                }
2758                        }
2759                } else if (netif_is_lag_master(upper_dev)) {
2760                        if (info->linking) {
2761                                err = mlxsw_sp_port_lag_join(mlxsw_sp_port,
2762                                                             upper_dev);
2763                                if (err) {
2764                                        netdev_err(dev, "Failed to join link aggregation\n");
2765                                        return NOTIFY_BAD;
2766                                }
2767                        } else {
2768                                err = mlxsw_sp_port_lag_leave(mlxsw_sp_port,
2769                                                              upper_dev);
2770                                if (err) {
2771                                        netdev_err(dev, "Failed to leave link aggregation\n");
2772                                        return NOTIFY_BAD;
2773                                }
2774                        }
2775                }
2776                break;
2777        }
2778
2779        return NOTIFY_DONE;
2780}
2781
2782static int mlxsw_sp_netdevice_port_lower_event(struct net_device *dev,
2783                                               unsigned long event, void *ptr)
2784{
2785        struct netdev_notifier_changelowerstate_info *info;
2786        struct mlxsw_sp_port *mlxsw_sp_port;
2787        int err;
2788
2789        mlxsw_sp_port = netdev_priv(dev);
2790        info = ptr;
2791
2792        switch (event) {
2793        case NETDEV_CHANGELOWERSTATE:
2794                if (netif_is_lag_port(dev) && mlxsw_sp_port->lagged) {
2795                        err = mlxsw_sp_port_lag_changed(mlxsw_sp_port,
2796                                                        info->lower_state_info);
2797                        if (err)
2798                                netdev_err(dev, "Failed to reflect link aggregation lower state change\n");
2799                }
2800                break;
2801        }
2802
2803        return NOTIFY_DONE;
2804}
2805
2806static int mlxsw_sp_netdevice_port_event(struct net_device *dev,
2807                                         unsigned long event, void *ptr)
2808{
2809        switch (event) {
2810        case NETDEV_PRECHANGEUPPER:
2811        case NETDEV_CHANGEUPPER:
2812                return mlxsw_sp_netdevice_port_upper_event(dev, event, ptr);
2813        case NETDEV_CHANGELOWERSTATE:
2814                return mlxsw_sp_netdevice_port_lower_event(dev, event, ptr);
2815        }
2816
2817        return NOTIFY_DONE;
2818}
2819
2820static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
2821                                        unsigned long event, void *ptr)
2822{
2823        struct net_device *dev;
2824        struct list_head *iter;
2825        int ret;
2826
2827        netdev_for_each_lower_dev(lag_dev, dev, iter) {
2828                if (mlxsw_sp_port_dev_check(dev)) {
2829                        ret = mlxsw_sp_netdevice_port_event(dev, event, ptr);
2830                        if (ret == NOTIFY_BAD)
2831                                return ret;
2832                }
2833        }
2834
2835        return NOTIFY_DONE;
2836}
2837
2838static struct mlxsw_sp_vfid *
2839mlxsw_sp_br_vfid_find(const struct mlxsw_sp *mlxsw_sp,
2840                      const struct net_device *br_dev)
2841{
2842        struct mlxsw_sp_vfid *vfid;
2843
2844        list_for_each_entry(vfid, &mlxsw_sp->br_vfids.list, list) {
2845                if (vfid->br_dev == br_dev)
2846                        return vfid;
2847        }
2848
2849        return NULL;
2850}
2851
2852static u16 mlxsw_sp_vfid_to_br_vfid(u16 vfid)
2853{
2854        return vfid - MLXSW_SP_VFID_PORT_MAX;
2855}
2856
2857static u16 mlxsw_sp_br_vfid_to_vfid(u16 br_vfid)
2858{
2859        return MLXSW_SP_VFID_PORT_MAX + br_vfid;
2860}
2861
2862static u16 mlxsw_sp_avail_br_vfid_get(const struct mlxsw_sp *mlxsw_sp)
2863{
2864        return find_first_zero_bit(mlxsw_sp->br_vfids.mapped,
2865                                   MLXSW_SP_VFID_BR_MAX);
2866}
2867
2868static struct mlxsw_sp_vfid *mlxsw_sp_br_vfid_create(struct mlxsw_sp *mlxsw_sp,
2869                                                     struct net_device *br_dev)
2870{
2871        struct device *dev = mlxsw_sp->bus_info->dev;
2872        struct mlxsw_sp_vfid *vfid;
2873        u16 n_vfid;
2874        int err;
2875
2876        n_vfid = mlxsw_sp_br_vfid_to_vfid(mlxsw_sp_avail_br_vfid_get(mlxsw_sp));
2877        if (n_vfid == MLXSW_SP_VFID_MAX) {
2878                dev_err(dev, "No available vFIDs\n");
2879                return ERR_PTR(-ERANGE);
2880        }
2881
2882        err = __mlxsw_sp_vfid_create(mlxsw_sp, n_vfid);
2883        if (err) {
2884                dev_err(dev, "Failed to create vFID=%d\n", n_vfid);
2885                return ERR_PTR(err);
2886        }
2887
2888        vfid = kzalloc(sizeof(*vfid), GFP_KERNEL);
2889        if (!vfid)
2890                goto err_allocate_vfid;
2891
2892        vfid->vfid = n_vfid;
2893        vfid->br_dev = br_dev;
2894
2895        list_add(&vfid->list, &mlxsw_sp->br_vfids.list);
2896        set_bit(mlxsw_sp_vfid_to_br_vfid(n_vfid), mlxsw_sp->br_vfids.mapped);
2897
2898        return vfid;
2899
2900err_allocate_vfid:
2901        __mlxsw_sp_vfid_destroy(mlxsw_sp, n_vfid);
2902        return ERR_PTR(-ENOMEM);
2903}
2904
2905static void mlxsw_sp_br_vfid_destroy(struct mlxsw_sp *mlxsw_sp,
2906                                     struct mlxsw_sp_vfid *vfid)
2907{
2908        u16 br_vfid = mlxsw_sp_vfid_to_br_vfid(vfid->vfid);
2909
2910        clear_bit(br_vfid, mlxsw_sp->br_vfids.mapped);
2911        list_del(&vfid->list);
2912
2913        __mlxsw_sp_vfid_destroy(mlxsw_sp, vfid->vfid);
2914
2915        kfree(vfid);
2916}
2917
2918static int mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport,
2919                                       struct net_device *br_dev,
2920                                       bool flush_fdb)
2921{
2922        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
2923        u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
2924        struct net_device *dev = mlxsw_sp_vport->dev;
2925        struct mlxsw_sp_vfid *vfid, *new_vfid;
2926        int err;
2927
2928        vfid = mlxsw_sp_br_vfid_find(mlxsw_sp, br_dev);
2929        if (!vfid) {
2930                WARN_ON(!vfid);
2931                return -EINVAL;
2932        }
2933
2934        /* We need a vFID to go back to after leaving the bridge's vFID. */
2935        new_vfid = mlxsw_sp_vfid_find(mlxsw_sp, vid);
2936        if (!new_vfid) {
2937                new_vfid = mlxsw_sp_vfid_create(mlxsw_sp, vid);
2938                if (IS_ERR(new_vfid)) {
2939                        netdev_err(dev, "Failed to create vFID for VID=%d\n",
2940                                   vid);
2941                        return PTR_ERR(new_vfid);
2942                }
2943        }
2944
2945        /* Invalidate existing {Port, VID} to vFID mapping and create a new
2946         * one for the new vFID.
2947         */
2948        err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport,
2949                                           MLXSW_REG_SVFA_MT_PORT_VID_TO_FID,
2950                                           false,
2951                                           mlxsw_sp_vfid_to_fid(vfid->vfid),
2952                                           vid);
2953        if (err) {
2954                netdev_err(dev, "Failed to invalidate {Port, VID} to vFID=%d mapping\n",
2955                           vfid->vfid);
2956                goto err_port_vid_to_fid_invalidate;
2957        }
2958
2959        err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport,
2960                                           MLXSW_REG_SVFA_MT_PORT_VID_TO_FID,
2961                                           true,
2962                                           mlxsw_sp_vfid_to_fid(new_vfid->vfid),
2963                                           vid);
2964        if (err) {
2965                netdev_err(dev, "Failed to map {Port, VID} to vFID=%d\n",
2966                           new_vfid->vfid);
2967                goto err_port_vid_to_fid_validate;
2968        }
2969
2970        err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false);
2971        if (err) {
2972                netdev_err(dev, "Failed to disable learning\n");
2973                goto err_port_vid_learning_set;
2974        }
2975
2976        err = mlxsw_sp_vport_flood_set(mlxsw_sp_vport, vfid->vfid, false,
2977                                       false);
2978        if (err) {
2979                netdev_err(dev, "Failed clear to clear flooding\n");
2980                goto err_vport_flood_set;
2981        }
2982
2983        err = mlxsw_sp_port_stp_state_set(mlxsw_sp_vport, vid,
2984                                          MLXSW_REG_SPMS_STATE_FORWARDING);
2985        if (err) {
2986                netdev_err(dev, "Failed to set STP state\n");
2987                goto err_port_stp_state_set;
2988        }
2989
2990        if (flush_fdb && mlxsw_sp_vport_fdb_flush(mlxsw_sp_vport))
2991                netdev_err(dev, "Failed to flush FDB\n");
2992
2993        /* Switch between the vFIDs and destroy the old one if needed. */
2994        new_vfid->nr_vports++;
2995        mlxsw_sp_vport->vport.vfid = new_vfid;
2996        vfid->nr_vports--;
2997        if (!vfid->nr_vports)
2998                mlxsw_sp_br_vfid_destroy(mlxsw_sp, vfid);
2999
3000        mlxsw_sp_vport->learning = 0;
3001        mlxsw_sp_vport->learning_sync = 0;
3002        mlxsw_sp_vport->uc_flood = 0;
3003        mlxsw_sp_vport->bridged = 0;
3004
3005        return 0;
3006
3007err_port_stp_state_set:
3008err_vport_flood_set:
3009err_port_vid_learning_set:
3010err_port_vid_to_fid_validate:
3011err_port_vid_to_fid_invalidate:
3012        /* Rollback vFID only if new. */
3013        if (!new_vfid->nr_vports)
3014                mlxsw_sp_vfid_destroy(mlxsw_sp, new_vfid);
3015        return err;
3016}
3017
3018static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport,
3019                                      struct net_device *br_dev)
3020{
3021        struct mlxsw_sp_vfid *old_vfid = mlxsw_sp_vport->vport.vfid;
3022        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
3023        u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
3024        struct net_device *dev = mlxsw_sp_vport->dev;
3025        struct mlxsw_sp_vfid *vfid;
3026        int err;
3027
3028        vfid = mlxsw_sp_br_vfid_find(mlxsw_sp, br_dev);
3029        if (!vfid) {
3030                vfid = mlxsw_sp_br_vfid_create(mlxsw_sp, br_dev);
3031                if (IS_ERR(vfid)) {
3032                        netdev_err(dev, "Failed to create bridge vFID\n");
3033                        return PTR_ERR(vfid);
3034                }
3035        }
3036
3037        err = mlxsw_sp_vport_flood_set(mlxsw_sp_vport, vfid->vfid, true, false);
3038        if (err) {
3039                netdev_err(dev, "Failed to setup flooding for vFID=%d\n",
3040                           vfid->vfid);
3041                goto err_port_flood_set;
3042        }
3043
3044        err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
3045        if (err) {
3046                netdev_err(dev, "Failed to enable learning\n");
3047                goto err_port_vid_learning_set;
3048        }
3049
3050        /* We need to invalidate existing {Port, VID} to vFID mapping and
3051         * create a new one for the bridge's vFID.
3052         */
3053        err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport,
3054                                           MLXSW_REG_SVFA_MT_PORT_VID_TO_FID,
3055                                           false,
3056                                           mlxsw_sp_vfid_to_fid(old_vfid->vfid),
3057                                           vid);
3058        if (err) {
3059                netdev_err(dev, "Failed to invalidate {Port, VID} to vFID=%d mapping\n",
3060                           old_vfid->vfid);
3061                goto err_port_vid_to_fid_invalidate;
3062        }
3063
3064        err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport,
3065                                           MLXSW_REG_SVFA_MT_PORT_VID_TO_FID,
3066                                           true,
3067                                           mlxsw_sp_vfid_to_fid(vfid->vfid),
3068                                           vid);
3069        if (err) {
3070                netdev_err(dev, "Failed to map {Port, VID} to vFID=%d\n",
3071                           vfid->vfid);
3072                goto err_port_vid_to_fid_validate;
3073        }
3074
3075        /* Switch between the vFIDs and destroy the old one if needed. */
3076        vfid->nr_vports++;
3077        mlxsw_sp_vport->vport.vfid = vfid;
3078        old_vfid->nr_vports--;
3079        if (!old_vfid->nr_vports)
3080                mlxsw_sp_vfid_destroy(mlxsw_sp, old_vfid);
3081
3082        mlxsw_sp_vport->learning = 1;
3083        mlxsw_sp_vport->learning_sync = 1;
3084        mlxsw_sp_vport->uc_flood = 1;
3085        mlxsw_sp_vport->bridged = 1;
3086
3087        return 0;
3088
3089err_port_vid_to_fid_validate:
3090        mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport,
3091                                     MLXSW_REG_SVFA_MT_PORT_VID_TO_FID, false,
3092                                     mlxsw_sp_vfid_to_fid(old_vfid->vfid), vid);
3093err_port_vid_to_fid_invalidate:
3094        mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false);
3095err_port_vid_learning_set:
3096        mlxsw_sp_vport_flood_set(mlxsw_sp_vport, vfid->vfid, false, false);
3097err_port_flood_set:
3098        if (!vfid->nr_vports)
3099                mlxsw_sp_br_vfid_destroy(mlxsw_sp, vfid);
3100        return err;
3101}
3102
3103static bool
3104mlxsw_sp_port_master_bridge_check(const struct mlxsw_sp_port *mlxsw_sp_port,
3105                                  const struct net_device *br_dev)
3106{
3107        struct mlxsw_sp_port *mlxsw_sp_vport;
3108
3109        list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list,
3110                            vport.list) {
3111                if (mlxsw_sp_vport_br_get(mlxsw_sp_vport) == br_dev)
3112                        return false;
3113        }
3114
3115        return true;
3116}
3117
3118static int mlxsw_sp_netdevice_vport_event(struct net_device *dev,
3119                                          unsigned long event, void *ptr,
3120                                          u16 vid)
3121{
3122        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
3123        struct netdev_notifier_changeupper_info *info = ptr;
3124        struct mlxsw_sp_port *mlxsw_sp_vport;
3125        struct net_device *upper_dev;
3126        int err;
3127
3128        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
3129
3130        switch (event) {
3131        case NETDEV_PRECHANGEUPPER:
3132                upper_dev = info->upper_dev;
3133                if (!info->master || !info->linking)
3134                        break;
3135                if (!netif_is_bridge_master(upper_dev))
3136                        return NOTIFY_BAD;
3137                /* We can't have multiple VLAN interfaces configured on
3138                 * the same port and being members in the same bridge.
3139                 */
3140                if (!mlxsw_sp_port_master_bridge_check(mlxsw_sp_port,
3141                                                       upper_dev))
3142                        return NOTIFY_BAD;
3143                break;
3144        case NETDEV_CHANGEUPPER:
3145                upper_dev = info->upper_dev;
3146                if (!info->master)
3147                        break;
3148                if (info->linking) {
3149                        if (!mlxsw_sp_vport) {
3150                                WARN_ON(!mlxsw_sp_vport);
3151                                return NOTIFY_BAD;
3152                        }
3153                        err = mlxsw_sp_vport_bridge_join(mlxsw_sp_vport,
3154                                                         upper_dev);
3155                        if (err) {
3156                                netdev_err(dev, "Failed to join bridge\n");
3157                                return NOTIFY_BAD;
3158                        }
3159                } else {
3160                        /* We ignore bridge's unlinking notifications if vPort
3161                         * is gone, since we already left the bridge when the
3162                         * VLAN device was unlinked from the real device.
3163                         */
3164                        if (!mlxsw_sp_vport)
3165                                return NOTIFY_DONE;
3166                        err = mlxsw_sp_vport_bridge_leave(mlxsw_sp_vport,
3167                                                          upper_dev, true);
3168                        if (err) {
3169                                netdev_err(dev, "Failed to leave bridge\n");
3170                                return NOTIFY_BAD;
3171                        }
3172                }
3173        }
3174
3175        return NOTIFY_DONE;
3176}
3177
3178static int mlxsw_sp_netdevice_lag_vport_event(struct net_device *lag_dev,
3179                                              unsigned long event, void *ptr,
3180                                              u16 vid)
3181{
3182        struct net_device *dev;
3183        struct list_head *iter;
3184        int ret;
3185
3186        netdev_for_each_lower_dev(lag_dev, dev, iter) {
3187                if (mlxsw_sp_port_dev_check(dev)) {
3188                        ret = mlxsw_sp_netdevice_vport_event(dev, event, ptr,
3189                                                             vid);
3190                        if (ret == NOTIFY_BAD)
3191                                return ret;
3192                }
3193        }
3194
3195        return NOTIFY_DONE;
3196}
3197
3198static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
3199                                         unsigned long event, void *ptr)
3200{
3201        struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
3202        u16 vid = vlan_dev_vlan_id(vlan_dev);
3203
3204        if (mlxsw_sp_port_dev_check(real_dev))
3205                return mlxsw_sp_netdevice_vport_event(real_dev, event, ptr,
3206                                                      vid);
3207        else if (netif_is_lag_master(real_dev))
3208                return mlxsw_sp_netdevice_lag_vport_event(real_dev, event, ptr,
3209                                                          vid);
3210
3211        return NOTIFY_DONE;
3212}
3213
3214static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
3215                                    unsigned long event, void *ptr)
3216{
3217        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
3218
3219        if (mlxsw_sp_port_dev_check(dev))
3220                return mlxsw_sp_netdevice_port_event(dev, event, ptr);
3221
3222        if (netif_is_lag_master(dev))
3223                return mlxsw_sp_netdevice_lag_event(dev, event, ptr);
3224
3225        if (is_vlan_dev(dev))
3226                return mlxsw_sp_netdevice_vlan_event(dev, event, ptr);
3227
3228        return NOTIFY_DONE;
3229}
3230
3231static struct notifier_block mlxsw_sp_netdevice_nb __read_mostly = {
3232        .notifier_call = mlxsw_sp_netdevice_event,
3233};
3234
3235static int __init mlxsw_sp_module_init(void)
3236{
3237        int err;
3238
3239        register_netdevice_notifier(&mlxsw_sp_netdevice_nb);
3240        err = mlxsw_core_driver_register(&mlxsw_sp_driver);
3241        if (err)
3242                goto err_core_driver_register;
3243        return 0;
3244
3245err_core_driver_register:
3246        unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb);
3247        return err;
3248}
3249
3250static void __exit mlxsw_sp_module_exit(void)
3251{
3252        mlxsw_core_driver_unregister(&mlxsw_sp_driver);
3253        unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb);
3254}
3255
3256module_init(mlxsw_sp_module_init);
3257module_exit(mlxsw_sp_module_exit);
3258
3259MODULE_LICENSE("Dual BSD/GPL");
3260MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
3261MODULE_DESCRIPTION("Mellanox Spectrum driver");
3262MODULE_MLXSW_DRIVER_ALIAS(MLXSW_DEVICE_KIND_SPECTRUM);
3263