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 <linux/notifier.h>
  53#include <linux/dcbnl.h>
  54#include <linux/inetdevice.h>
  55#include <net/switchdev.h>
  56#include <generated/utsrelease.h>
  57#include <net/pkt_cls.h>
  58#include <net/tc_act/tc_mirred.h>
  59#include <net/netevent.h>
  60
  61#include "spectrum.h"
  62#include "core.h"
  63#include "reg.h"
  64#include "port.h"
  65#include "trap.h"
  66#include "txheader.h"
  67
  68static const char mlxsw_sp_driver_name[] = "mlxsw_spectrum";
  69static const char mlxsw_sp_driver_version[] = "1.0";
  70
  71/* tx_hdr_version
  72 * Tx header version.
  73 * Must be set to 1.
  74 */
  75MLXSW_ITEM32(tx, hdr, version, 0x00, 28, 4);
  76
  77/* tx_hdr_ctl
  78 * Packet control type.
  79 * 0 - Ethernet control (e.g. EMADs, LACP)
  80 * 1 - Ethernet data
  81 */
  82MLXSW_ITEM32(tx, hdr, ctl, 0x00, 26, 2);
  83
  84/* tx_hdr_proto
  85 * Packet protocol type. Must be set to 1 (Ethernet).
  86 */
  87MLXSW_ITEM32(tx, hdr, proto, 0x00, 21, 3);
  88
  89/* tx_hdr_rx_is_router
  90 * Packet is sent from the router. Valid for data packets only.
  91 */
  92MLXSW_ITEM32(tx, hdr, rx_is_router, 0x00, 19, 1);
  93
  94/* tx_hdr_fid_valid
  95 * Indicates if the 'fid' field is valid and should be used for
  96 * forwarding lookup. Valid for data packets only.
  97 */
  98MLXSW_ITEM32(tx, hdr, fid_valid, 0x00, 16, 1);
  99
 100/* tx_hdr_swid
 101 * Switch partition ID. Must be set to 0.
 102 */
 103MLXSW_ITEM32(tx, hdr, swid, 0x00, 12, 3);
 104
 105/* tx_hdr_control_tclass
 106 * Indicates if the packet should use the control TClass and not one
 107 * of the data TClasses.
 108 */
 109MLXSW_ITEM32(tx, hdr, control_tclass, 0x00, 6, 1);
 110
 111/* tx_hdr_etclass
 112 * Egress TClass to be used on the egress device on the egress port.
 113 */
 114MLXSW_ITEM32(tx, hdr, etclass, 0x00, 0, 4);
 115
 116/* tx_hdr_port_mid
 117 * Destination local port for unicast packets.
 118 * Destination multicast ID for multicast packets.
 119 *
 120 * Control packets are directed to a specific egress port, while data
 121 * packets are transmitted through the CPU port (0) into the switch partition,
 122 * where forwarding rules are applied.
 123 */
 124MLXSW_ITEM32(tx, hdr, port_mid, 0x04, 16, 16);
 125
 126/* tx_hdr_fid
 127 * Forwarding ID used for L2 forwarding lookup. Valid only if 'fid_valid' is
 128 * set, otherwise calculated based on the packet's VID using VID to FID mapping.
 129 * Valid for data packets only.
 130 */
 131MLXSW_ITEM32(tx, hdr, fid, 0x08, 0, 16);
 132
 133/* tx_hdr_type
 134 * 0 - Data packets
 135 * 6 - Control packets
 136 */
 137MLXSW_ITEM32(tx, hdr, type, 0x0C, 0, 4);
 138
 139static bool mlxsw_sp_port_dev_check(const struct net_device *dev);
 140
 141static void mlxsw_sp_txhdr_construct(struct sk_buff *skb,
 142                                     const struct mlxsw_tx_info *tx_info)
 143{
 144        char *txhdr = skb_push(skb, MLXSW_TXHDR_LEN);
 145
 146        memset(txhdr, 0, MLXSW_TXHDR_LEN);
 147
 148        mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1);
 149        mlxsw_tx_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL);
 150        mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH);
 151        mlxsw_tx_hdr_swid_set(txhdr, 0);
 152        mlxsw_tx_hdr_control_tclass_set(txhdr, 1);
 153        mlxsw_tx_hdr_port_mid_set(txhdr, tx_info->local_port);
 154        mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL);
 155}
 156
 157static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp)
 158{
 159        char spad_pl[MLXSW_REG_SPAD_LEN];
 160        int err;
 161
 162        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(spad), spad_pl);
 163        if (err)
 164                return err;
 165        mlxsw_reg_spad_base_mac_memcpy_from(spad_pl, mlxsw_sp->base_mac);
 166        return 0;
 167}
 168
 169static int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
 170{
 171        struct mlxsw_resources *resources;
 172        int i;
 173
 174        resources = mlxsw_core_resources_get(mlxsw_sp->core);
 175        if (!resources->max_span_valid)
 176                return -EIO;
 177
 178        mlxsw_sp->span.entries_count = resources->max_span;
 179        mlxsw_sp->span.entries = kcalloc(mlxsw_sp->span.entries_count,
 180                                         sizeof(struct mlxsw_sp_span_entry),
 181                                         GFP_KERNEL);
 182        if (!mlxsw_sp->span.entries)
 183                return -ENOMEM;
 184
 185        for (i = 0; i < mlxsw_sp->span.entries_count; i++)
 186                INIT_LIST_HEAD(&mlxsw_sp->span.entries[i].bound_ports_list);
 187
 188        return 0;
 189}
 190
 191static void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
 192{
 193        int i;
 194
 195        for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
 196                struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
 197
 198                WARN_ON_ONCE(!list_empty(&curr->bound_ports_list));
 199        }
 200        kfree(mlxsw_sp->span.entries);
 201}
 202
 203static struct mlxsw_sp_span_entry *
 204mlxsw_sp_span_entry_create(struct mlxsw_sp_port *port)
 205{
 206        struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
 207        struct mlxsw_sp_span_entry *span_entry;
 208        char mpat_pl[MLXSW_REG_MPAT_LEN];
 209        u8 local_port = port->local_port;
 210        int index;
 211        int i;
 212        int err;
 213
 214        /* find a free entry to use */
 215        index = -1;
 216        for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
 217                if (!mlxsw_sp->span.entries[i].used) {
 218                        index = i;
 219                        span_entry = &mlxsw_sp->span.entries[i];
 220                        break;
 221                }
 222        }
 223        if (index < 0)
 224                return NULL;
 225
 226        /* create a new port analayzer entry for local_port */
 227        mlxsw_reg_mpat_pack(mpat_pl, index, local_port, true);
 228        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
 229        if (err)
 230                return NULL;
 231
 232        span_entry->used = true;
 233        span_entry->id = index;
 234        span_entry->ref_count = 1;
 235        span_entry->local_port = local_port;
 236        return span_entry;
 237}
 238
 239static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp,
 240                                        struct mlxsw_sp_span_entry *span_entry)
 241{
 242        u8 local_port = span_entry->local_port;
 243        char mpat_pl[MLXSW_REG_MPAT_LEN];
 244        int pa_id = span_entry->id;
 245
 246        mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, false);
 247        mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
 248        span_entry->used = false;
 249}
 250
 251static struct mlxsw_sp_span_entry *
 252mlxsw_sp_span_entry_find(struct mlxsw_sp_port *port)
 253{
 254        struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
 255        int i;
 256
 257        for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
 258                struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
 259
 260                if (curr->used && curr->local_port == port->local_port)
 261                        return curr;
 262        }
 263        return NULL;
 264}
 265
 266static struct mlxsw_sp_span_entry
 267*mlxsw_sp_span_entry_get(struct mlxsw_sp_port *port)
 268{
 269        struct mlxsw_sp_span_entry *span_entry;
 270
 271        span_entry = mlxsw_sp_span_entry_find(port);
 272        if (span_entry) {
 273                /* Already exists, just take a reference */
 274                span_entry->ref_count++;
 275                return span_entry;
 276        }
 277
 278        return mlxsw_sp_span_entry_create(port);
 279}
 280
 281static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
 282                                   struct mlxsw_sp_span_entry *span_entry)
 283{
 284        WARN_ON(!span_entry->ref_count);
 285        if (--span_entry->ref_count == 0)
 286                mlxsw_sp_span_entry_destroy(mlxsw_sp, span_entry);
 287        return 0;
 288}
 289
 290static bool mlxsw_sp_span_is_egress_mirror(struct mlxsw_sp_port *port)
 291{
 292        struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
 293        struct mlxsw_sp_span_inspected_port *p;
 294        int i;
 295
 296        for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
 297                struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
 298
 299                list_for_each_entry(p, &curr->bound_ports_list, list)
 300                        if (p->local_port == port->local_port &&
 301                            p->type == MLXSW_SP_SPAN_EGRESS)
 302                                return true;
 303        }
 304
 305        return false;
 306}
 307
 308static int mlxsw_sp_span_mtu_to_buffsize(int mtu)
 309{
 310        return MLXSW_SP_BYTES_TO_CELLS(mtu * 5 / 2) + 1;
 311}
 312
 313static int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
 314{
 315        struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
 316        char sbib_pl[MLXSW_REG_SBIB_LEN];
 317        int err;
 318
 319        /* If port is egress mirrored, the shared buffer size should be
 320         * updated according to the mtu value
 321         */
 322        if (mlxsw_sp_span_is_egress_mirror(port)) {
 323                mlxsw_reg_sbib_pack(sbib_pl, port->local_port,
 324                                    mlxsw_sp_span_mtu_to_buffsize(mtu));
 325                err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
 326                if (err) {
 327                        netdev_err(port->dev, "Could not update shared buffer for mirroring\n");
 328                        return err;
 329                }
 330        }
 331
 332        return 0;
 333}
 334
 335static struct mlxsw_sp_span_inspected_port *
 336mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port,
 337                                    struct mlxsw_sp_span_entry *span_entry)
 338{
 339        struct mlxsw_sp_span_inspected_port *p;
 340
 341        list_for_each_entry(p, &span_entry->bound_ports_list, list)
 342                if (port->local_port == p->local_port)
 343                        return p;
 344        return NULL;
 345}
 346
 347static int
 348mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
 349                                  struct mlxsw_sp_span_entry *span_entry,
 350                                  enum mlxsw_sp_span_type type)
 351{
 352        struct mlxsw_sp_span_inspected_port *inspected_port;
 353        struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
 354        char mpar_pl[MLXSW_REG_MPAR_LEN];
 355        char sbib_pl[MLXSW_REG_SBIB_LEN];
 356        int pa_id = span_entry->id;
 357        int err;
 358
 359        /* if it is an egress SPAN, bind a shared buffer to it */
 360        if (type == MLXSW_SP_SPAN_EGRESS) {
 361                mlxsw_reg_sbib_pack(sbib_pl, port->local_port,
 362                                    mlxsw_sp_span_mtu_to_buffsize(port->dev->mtu));
 363                err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
 364                if (err) {
 365                        netdev_err(port->dev, "Could not create shared buffer for mirroring\n");
 366                        return err;
 367                }
 368        }
 369
 370        /* bind the port to the SPAN entry */
 371        mlxsw_reg_mpar_pack(mpar_pl, port->local_port,
 372                            (enum mlxsw_reg_mpar_i_e) type, true, pa_id);
 373        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl);
 374        if (err)
 375                goto err_mpar_reg_write;
 376
 377        inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL);
 378        if (!inspected_port) {
 379                err = -ENOMEM;
 380                goto err_inspected_port_alloc;
 381        }
 382        inspected_port->local_port = port->local_port;
 383        inspected_port->type = type;
 384        list_add_tail(&inspected_port->list, &span_entry->bound_ports_list);
 385
 386        return 0;
 387
 388err_mpar_reg_write:
 389err_inspected_port_alloc:
 390        if (type == MLXSW_SP_SPAN_EGRESS) {
 391                mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
 392                mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
 393        }
 394        return err;
 395}
 396
 397static void
 398mlxsw_sp_span_inspected_port_unbind(struct mlxsw_sp_port *port,
 399                                    struct mlxsw_sp_span_entry *span_entry,
 400                                    enum mlxsw_sp_span_type type)
 401{
 402        struct mlxsw_sp_span_inspected_port *inspected_port;
 403        struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
 404        char mpar_pl[MLXSW_REG_MPAR_LEN];
 405        char sbib_pl[MLXSW_REG_SBIB_LEN];
 406        int pa_id = span_entry->id;
 407
 408        inspected_port = mlxsw_sp_span_entry_bound_port_find(port, span_entry);
 409        if (!inspected_port)
 410                return;
 411
 412        /* remove the inspected port */
 413        mlxsw_reg_mpar_pack(mpar_pl, port->local_port,
 414                            (enum mlxsw_reg_mpar_i_e) type, false, pa_id);
 415        mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl);
 416
 417        /* remove the SBIB buffer if it was egress SPAN */
 418        if (type == MLXSW_SP_SPAN_EGRESS) {
 419                mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
 420                mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
 421        }
 422
 423        mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
 424
 425        list_del(&inspected_port->list);
 426        kfree(inspected_port);
 427}
 428
 429static int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
 430                                    struct mlxsw_sp_port *to,
 431                                    enum mlxsw_sp_span_type type)
 432{
 433        struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp;
 434        struct mlxsw_sp_span_entry *span_entry;
 435        int err;
 436
 437        span_entry = mlxsw_sp_span_entry_get(to);
 438        if (!span_entry)
 439                return -ENOENT;
 440
 441        netdev_dbg(from->dev, "Adding inspected port to SPAN entry %d\n",
 442                   span_entry->id);
 443
 444        err = mlxsw_sp_span_inspected_port_bind(from, span_entry, type);
 445        if (err)
 446                goto err_port_bind;
 447
 448        return 0;
 449
 450err_port_bind:
 451        mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
 452        return err;
 453}
 454
 455static void mlxsw_sp_span_mirror_remove(struct mlxsw_sp_port *from,
 456                                        struct mlxsw_sp_port *to,
 457                                        enum mlxsw_sp_span_type type)
 458{
 459        struct mlxsw_sp_span_entry *span_entry;
 460
 461        span_entry = mlxsw_sp_span_entry_find(to);
 462        if (!span_entry) {
 463                netdev_err(from->dev, "no span entry found\n");
 464                return;
 465        }
 466
 467        netdev_dbg(from->dev, "removing inspected port from SPAN entry %d\n",
 468                   span_entry->id);
 469        mlxsw_sp_span_inspected_port_unbind(from, span_entry, type);
 470}
 471
 472static int mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port *mlxsw_sp_port,
 473                                          bool is_up)
 474{
 475        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 476        char paos_pl[MLXSW_REG_PAOS_LEN];
 477
 478        mlxsw_reg_paos_pack(paos_pl, mlxsw_sp_port->local_port,
 479                            is_up ? MLXSW_PORT_ADMIN_STATUS_UP :
 480                            MLXSW_PORT_ADMIN_STATUS_DOWN);
 481        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(paos), paos_pl);
 482}
 483
 484static int mlxsw_sp_port_dev_addr_set(struct mlxsw_sp_port *mlxsw_sp_port,
 485                                      unsigned char *addr)
 486{
 487        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 488        char ppad_pl[MLXSW_REG_PPAD_LEN];
 489
 490        mlxsw_reg_ppad_pack(ppad_pl, true, mlxsw_sp_port->local_port);
 491        mlxsw_reg_ppad_mac_memcpy_to(ppad_pl, addr);
 492        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppad), ppad_pl);
 493}
 494
 495static int mlxsw_sp_port_dev_addr_init(struct mlxsw_sp_port *mlxsw_sp_port)
 496{
 497        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 498        unsigned char *addr = mlxsw_sp_port->dev->dev_addr;
 499
 500        ether_addr_copy(addr, mlxsw_sp->base_mac);
 501        addr[ETH_ALEN - 1] += mlxsw_sp_port->local_port;
 502        return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr);
 503}
 504
 505static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
 506{
 507        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 508        char pmtu_pl[MLXSW_REG_PMTU_LEN];
 509        int max_mtu;
 510        int err;
 511
 512        mtu += MLXSW_TXHDR_LEN + ETH_HLEN;
 513        mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, 0);
 514        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
 515        if (err)
 516                return err;
 517        max_mtu = mlxsw_reg_pmtu_max_mtu_get(pmtu_pl);
 518
 519        if (mtu > max_mtu)
 520                return -EINVAL;
 521
 522        mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, mtu);
 523        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
 524}
 525
 526static int __mlxsw_sp_port_swid_set(struct mlxsw_sp *mlxsw_sp, u8 local_port,
 527                                    u8 swid)
 528{
 529        char pspa_pl[MLXSW_REG_PSPA_LEN];
 530
 531        mlxsw_reg_pspa_pack(pspa_pl, swid, local_port);
 532        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pspa), pspa_pl);
 533}
 534
 535static int mlxsw_sp_port_swid_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 swid)
 536{
 537        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 538
 539        return __mlxsw_sp_port_swid_set(mlxsw_sp, mlxsw_sp_port->local_port,
 540                                        swid);
 541}
 542
 543static int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port,
 544                                     bool enable)
 545{
 546        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 547        char svpe_pl[MLXSW_REG_SVPE_LEN];
 548
 549        mlxsw_reg_svpe_pack(svpe_pl, mlxsw_sp_port->local_port, enable);
 550        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svpe), svpe_pl);
 551}
 552
 553int mlxsw_sp_port_vid_to_fid_set(struct mlxsw_sp_port *mlxsw_sp_port,
 554                                 enum mlxsw_reg_svfa_mt mt, bool valid, u16 fid,
 555                                 u16 vid)
 556{
 557        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 558        char svfa_pl[MLXSW_REG_SVFA_LEN];
 559
 560        mlxsw_reg_svfa_pack(svfa_pl, mlxsw_sp_port->local_port, mt, valid,
 561                            fid, vid);
 562        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
 563}
 564
 565int __mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
 566                                     u16 vid_begin, u16 vid_end,
 567                                     bool learn_enable)
 568{
 569        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 570        char *spvmlr_pl;
 571        int err;
 572
 573        spvmlr_pl = kmalloc(MLXSW_REG_SPVMLR_LEN, GFP_KERNEL);
 574        if (!spvmlr_pl)
 575                return -ENOMEM;
 576        mlxsw_reg_spvmlr_pack(spvmlr_pl, mlxsw_sp_port->local_port, vid_begin,
 577                              vid_end, learn_enable);
 578        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvmlr), spvmlr_pl);
 579        kfree(spvmlr_pl);
 580        return err;
 581}
 582
 583static int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
 584                                          u16 vid, bool learn_enable)
 585{
 586        return __mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, vid,
 587                                                learn_enable);
 588}
 589
 590static int
 591mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port *mlxsw_sp_port)
 592{
 593        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 594        char sspr_pl[MLXSW_REG_SSPR_LEN];
 595
 596        mlxsw_reg_sspr_pack(sspr_pl, mlxsw_sp_port->local_port);
 597        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sspr), sspr_pl);
 598}
 599
 600static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
 601                                         u8 local_port, u8 *p_module,
 602                                         u8 *p_width, u8 *p_lane)
 603{
 604        char pmlp_pl[MLXSW_REG_PMLP_LEN];
 605        int err;
 606
 607        mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
 608        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
 609        if (err)
 610                return err;
 611        *p_module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
 612        *p_width = mlxsw_reg_pmlp_width_get(pmlp_pl);
 613        *p_lane = mlxsw_reg_pmlp_tx_lane_get(pmlp_pl, 0);
 614        return 0;
 615}
 616
 617static int mlxsw_sp_port_module_map(struct mlxsw_sp *mlxsw_sp, u8 local_port,
 618                                    u8 module, u8 width, u8 lane)
 619{
 620        char pmlp_pl[MLXSW_REG_PMLP_LEN];
 621        int i;
 622
 623        mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
 624        mlxsw_reg_pmlp_width_set(pmlp_pl, width);
 625        for (i = 0; i < width; i++) {
 626                mlxsw_reg_pmlp_module_set(pmlp_pl, i, module);
 627                mlxsw_reg_pmlp_tx_lane_set(pmlp_pl, i, lane + i);  /* Rx & Tx */
 628        }
 629
 630        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
 631}
 632
 633static int mlxsw_sp_port_module_unmap(struct mlxsw_sp *mlxsw_sp, u8 local_port)
 634{
 635        char pmlp_pl[MLXSW_REG_PMLP_LEN];
 636
 637        mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
 638        mlxsw_reg_pmlp_width_set(pmlp_pl, 0);
 639        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
 640}
 641
 642static int mlxsw_sp_port_open(struct net_device *dev)
 643{
 644        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 645        int err;
 646
 647        err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
 648        if (err)
 649                return err;
 650        netif_start_queue(dev);
 651        return 0;
 652}
 653
 654static int mlxsw_sp_port_stop(struct net_device *dev)
 655{
 656        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 657
 658        netif_stop_queue(dev);
 659        return mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
 660}
 661
 662static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
 663                                      struct net_device *dev)
 664{
 665        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 666        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 667        struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
 668        const struct mlxsw_tx_info tx_info = {
 669                .local_port = mlxsw_sp_port->local_port,
 670                .is_emad = false,
 671        };
 672        u64 len;
 673        int err;
 674
 675        if (mlxsw_core_skb_transmit_busy(mlxsw_sp->core, &tx_info))
 676                return NETDEV_TX_BUSY;
 677
 678        if (unlikely(skb_headroom(skb) < MLXSW_TXHDR_LEN)) {
 679                struct sk_buff *skb_orig = skb;
 680
 681                skb = skb_realloc_headroom(skb, MLXSW_TXHDR_LEN);
 682                if (!skb) {
 683                        this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
 684                        dev_kfree_skb_any(skb_orig);
 685                        return NETDEV_TX_OK;
 686                }
 687        }
 688
 689        if (eth_skb_pad(skb)) {
 690                this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
 691                return NETDEV_TX_OK;
 692        }
 693
 694        mlxsw_sp_txhdr_construct(skb, &tx_info);
 695        /* TX header is consumed by HW on the way so we shouldn't count its
 696         * bytes as being sent.
 697         */
 698        len = skb->len - MLXSW_TXHDR_LEN;
 699
 700        /* Due to a race we might fail here because of a full queue. In that
 701         * unlikely case we simply drop the packet.
 702         */
 703        err = mlxsw_core_skb_transmit(mlxsw_sp->core, skb, &tx_info);
 704
 705        if (!err) {
 706                pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
 707                u64_stats_update_begin(&pcpu_stats->syncp);
 708                pcpu_stats->tx_packets++;
 709                pcpu_stats->tx_bytes += len;
 710                u64_stats_update_end(&pcpu_stats->syncp);
 711        } else {
 712                this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
 713                dev_kfree_skb_any(skb);
 714        }
 715        return NETDEV_TX_OK;
 716}
 717
 718static void mlxsw_sp_set_rx_mode(struct net_device *dev)
 719{
 720}
 721
 722static int mlxsw_sp_port_set_mac_address(struct net_device *dev, void *p)
 723{
 724        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 725        struct sockaddr *addr = p;
 726        int err;
 727
 728        if (!is_valid_ether_addr(addr->sa_data))
 729                return -EADDRNOTAVAIL;
 730
 731        err = mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr->sa_data);
 732        if (err)
 733                return err;
 734        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 735        return 0;
 736}
 737
 738static void mlxsw_sp_pg_buf_pack(char *pbmc_pl, int pg_index, int mtu,
 739                                 bool pause_en, bool pfc_en, u16 delay)
 740{
 741        u16 pg_size = 2 * MLXSW_SP_BYTES_TO_CELLS(mtu);
 742
 743        delay = pfc_en ? mlxsw_sp_pfc_delay_get(mtu, delay) :
 744                         MLXSW_SP_PAUSE_DELAY;
 745
 746        if (pause_en || pfc_en)
 747                mlxsw_reg_pbmc_lossless_buffer_pack(pbmc_pl, pg_index,
 748                                                    pg_size + delay, pg_size);
 749        else
 750                mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, pg_index, pg_size);
 751}
 752
 753int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
 754                                 u8 *prio_tc, bool pause_en,
 755                                 struct ieee_pfc *my_pfc)
 756{
 757        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 758        u8 pfc_en = !!my_pfc ? my_pfc->pfc_en : 0;
 759        u16 delay = !!my_pfc ? my_pfc->delay : 0;
 760        char pbmc_pl[MLXSW_REG_PBMC_LEN];
 761        int i, j, err;
 762
 763        mlxsw_reg_pbmc_pack(pbmc_pl, mlxsw_sp_port->local_port, 0, 0);
 764        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
 765        if (err)
 766                return err;
 767
 768        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 769                bool configure = false;
 770                bool pfc = false;
 771
 772                for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) {
 773                        if (prio_tc[j] == i) {
 774                                pfc = pfc_en & BIT(j);
 775                                configure = true;
 776                                break;
 777                        }
 778                }
 779
 780                if (!configure)
 781                        continue;
 782                mlxsw_sp_pg_buf_pack(pbmc_pl, i, mtu, pause_en, pfc, delay);
 783        }
 784
 785        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
 786}
 787
 788static int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
 789                                      int mtu, bool pause_en)
 790{
 791        u8 def_prio_tc[IEEE_8021QAZ_MAX_TCS] = {0};
 792        bool dcb_en = !!mlxsw_sp_port->dcb.ets;
 793        struct ieee_pfc *my_pfc;
 794        u8 *prio_tc;
 795
 796        prio_tc = dcb_en ? mlxsw_sp_port->dcb.ets->prio_tc : def_prio_tc;
 797        my_pfc = dcb_en ? mlxsw_sp_port->dcb.pfc : NULL;
 798
 799        return __mlxsw_sp_port_headroom_set(mlxsw_sp_port, mtu, prio_tc,
 800                                            pause_en, my_pfc);
 801}
 802
 803static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu)
 804{
 805        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 806        bool pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
 807        int err;
 808
 809        err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, mtu, pause_en);
 810        if (err)
 811                return err;
 812        err = mlxsw_sp_span_port_mtu_update(mlxsw_sp_port, mtu);
 813        if (err)
 814                goto err_span_port_mtu_update;
 815        err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, mtu);
 816        if (err)
 817                goto err_port_mtu_set;
 818        dev->mtu = mtu;
 819        return 0;
 820
 821err_port_mtu_set:
 822        mlxsw_sp_span_port_mtu_update(mlxsw_sp_port, dev->mtu);
 823err_span_port_mtu_update:
 824        mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
 825        return err;
 826}
 827
 828static int
 829mlxsw_sp_port_get_sw_stats64(const struct net_device *dev,
 830                             struct rtnl_link_stats64 *stats)
 831{
 832        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 833        struct mlxsw_sp_port_pcpu_stats *p;
 834        u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
 835        u32 tx_dropped = 0;
 836        unsigned int start;
 837        int i;
 838
 839        for_each_possible_cpu(i) {
 840                p = per_cpu_ptr(mlxsw_sp_port->pcpu_stats, i);
 841                do {
 842                        start = u64_stats_fetch_begin_irq(&p->syncp);
 843                        rx_packets      = p->rx_packets;
 844                        rx_bytes        = p->rx_bytes;
 845                        tx_packets      = p->tx_packets;
 846                        tx_bytes        = p->tx_bytes;
 847                } while (u64_stats_fetch_retry_irq(&p->syncp, start));
 848
 849                stats->rx_packets       += rx_packets;
 850                stats->rx_bytes         += rx_bytes;
 851                stats->tx_packets       += tx_packets;
 852                stats->tx_bytes         += tx_bytes;
 853                /* tx_dropped is u32, updated without syncp protection. */
 854                tx_dropped      += p->tx_dropped;
 855        }
 856        stats->tx_dropped       = tx_dropped;
 857        return 0;
 858}
 859
 860static bool mlxsw_sp_port_has_offload_stats(int attr_id)
 861{
 862        switch (attr_id) {
 863        case IFLA_OFFLOAD_XSTATS_CPU_HIT:
 864                return true;
 865        }
 866
 867        return false;
 868}
 869
 870static int mlxsw_sp_port_get_offload_stats(int attr_id, const struct net_device *dev,
 871                                           void *sp)
 872{
 873        switch (attr_id) {
 874        case IFLA_OFFLOAD_XSTATS_CPU_HIT:
 875                return mlxsw_sp_port_get_sw_stats64(dev, sp);
 876        }
 877
 878        return -EINVAL;
 879}
 880
 881static int mlxsw_sp_port_get_stats_raw(struct net_device *dev, int grp,
 882                                       int prio, char *ppcnt_pl)
 883{
 884        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 885        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 886
 887        mlxsw_reg_ppcnt_pack(ppcnt_pl, mlxsw_sp_port->local_port, grp, prio);
 888        return mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ppcnt), ppcnt_pl);
 889}
 890
 891static int mlxsw_sp_port_get_hw_stats(struct net_device *dev,
 892                                      struct rtnl_link_stats64 *stats)
 893{
 894        char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
 895        int err;
 896
 897        err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_IEEE_8023_CNT,
 898                                          0, ppcnt_pl);
 899        if (err)
 900                goto out;
 901
 902        stats->tx_packets =
 903                mlxsw_reg_ppcnt_a_frames_transmitted_ok_get(ppcnt_pl);
 904        stats->rx_packets =
 905                mlxsw_reg_ppcnt_a_frames_received_ok_get(ppcnt_pl);
 906        stats->tx_bytes =
 907                mlxsw_reg_ppcnt_a_octets_transmitted_ok_get(ppcnt_pl);
 908        stats->rx_bytes =
 909                mlxsw_reg_ppcnt_a_octets_received_ok_get(ppcnt_pl);
 910        stats->multicast =
 911                mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get(ppcnt_pl);
 912
 913        stats->rx_crc_errors =
 914                mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get(ppcnt_pl);
 915        stats->rx_frame_errors =
 916                mlxsw_reg_ppcnt_a_alignment_errors_get(ppcnt_pl);
 917
 918        stats->rx_length_errors = (
 919                mlxsw_reg_ppcnt_a_in_range_length_errors_get(ppcnt_pl) +
 920                mlxsw_reg_ppcnt_a_out_of_range_length_field_get(ppcnt_pl) +
 921                mlxsw_reg_ppcnt_a_frame_too_long_errors_get(ppcnt_pl));
 922
 923        stats->rx_errors = (stats->rx_crc_errors +
 924                stats->rx_frame_errors + stats->rx_length_errors);
 925
 926out:
 927        return err;
 928}
 929
 930static void update_stats_cache(struct work_struct *work)
 931{
 932        struct mlxsw_sp_port *mlxsw_sp_port =
 933                container_of(work, struct mlxsw_sp_port,
 934                             hw_stats.update_dw.work);
 935
 936        if (!netif_carrier_ok(mlxsw_sp_port->dev))
 937                goto out;
 938
 939        mlxsw_sp_port_get_hw_stats(mlxsw_sp_port->dev,
 940                                   mlxsw_sp_port->hw_stats.cache);
 941
 942out:
 943        mlxsw_core_schedule_dw(&mlxsw_sp_port->hw_stats.update_dw,
 944                               MLXSW_HW_STATS_UPDATE_TIME);
 945}
 946
 947/* Return the stats from a cache that is updated periodically,
 948 * as this function might get called in an atomic context.
 949 */
 950static struct rtnl_link_stats64 *
 951mlxsw_sp_port_get_stats64(struct net_device *dev,
 952                          struct rtnl_link_stats64 *stats)
 953{
 954        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 955
 956        memcpy(stats, mlxsw_sp_port->hw_stats.cache, sizeof(*stats));
 957
 958        return stats;
 959}
 960
 961int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin,
 962                           u16 vid_end, bool is_member, bool untagged)
 963{
 964        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 965        char *spvm_pl;
 966        int err;
 967
 968        spvm_pl = kmalloc(MLXSW_REG_SPVM_LEN, GFP_KERNEL);
 969        if (!spvm_pl)
 970                return -ENOMEM;
 971
 972        mlxsw_reg_spvm_pack(spvm_pl, mlxsw_sp_port->local_port, vid_begin,
 973                            vid_end, is_member, untagged);
 974        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvm), spvm_pl);
 975        kfree(spvm_pl);
 976        return err;
 977}
 978
 979static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
 980{
 981        enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
 982        u16 vid, last_visited_vid;
 983        int err;
 984
 985        for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) {
 986                err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_port, mt, true, vid,
 987                                                   vid);
 988                if (err) {
 989                        last_visited_vid = vid;
 990                        goto err_port_vid_to_fid_set;
 991                }
 992        }
 993
 994        err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true);
 995        if (err) {
 996                last_visited_vid = VLAN_N_VID;
 997                goto err_port_vid_to_fid_set;
 998        }
 999
1000        return 0;
1001
1002err_port_vid_to_fid_set:
1003        for_each_set_bit(vid, mlxsw_sp_port->active_vlans, last_visited_vid)
1004                mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_port, mt, false, vid,
1005                                             vid);
1006        return err;
1007}
1008
1009static int mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
1010{
1011        enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
1012        u16 vid;
1013        int err;
1014
1015        err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
1016        if (err)
1017                return err;
1018
1019        for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) {
1020                err = mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_port, mt, false,
1021                                                   vid, vid);
1022                if (err)
1023                        return err;
1024        }
1025
1026        return 0;
1027}
1028
1029static struct mlxsw_sp_port *
1030mlxsw_sp_port_vport_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
1031{
1032        struct mlxsw_sp_port *mlxsw_sp_vport;
1033
1034        mlxsw_sp_vport = kzalloc(sizeof(*mlxsw_sp_vport), GFP_KERNEL);
1035        if (!mlxsw_sp_vport)
1036                return NULL;
1037
1038        /* dev will be set correctly after the VLAN device is linked
1039         * with the real device. In case of bridge SELF invocation, dev
1040         * will remain as is.
1041         */
1042        mlxsw_sp_vport->dev = mlxsw_sp_port->dev;
1043        mlxsw_sp_vport->mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1044        mlxsw_sp_vport->local_port = mlxsw_sp_port->local_port;
1045        mlxsw_sp_vport->stp_state = BR_STATE_FORWARDING;
1046        mlxsw_sp_vport->lagged = mlxsw_sp_port->lagged;
1047        mlxsw_sp_vport->lag_id = mlxsw_sp_port->lag_id;
1048        mlxsw_sp_vport->vport.vid = vid;
1049
1050        list_add(&mlxsw_sp_vport->vport.list, &mlxsw_sp_port->vports_list);
1051
1052        return mlxsw_sp_vport;
1053}
1054
1055static void mlxsw_sp_port_vport_destroy(struct mlxsw_sp_port *mlxsw_sp_vport)
1056{
1057        list_del(&mlxsw_sp_vport->vport.list);
1058        kfree(mlxsw_sp_vport);
1059}
1060
1061static int mlxsw_sp_port_add_vid(struct net_device *dev,
1062                                 __be16 __always_unused proto, u16 vid)
1063{
1064        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1065        struct mlxsw_sp_port *mlxsw_sp_vport;
1066        bool untagged = vid == 1;
1067        int err;
1068
1069        /* VLAN 0 is added to HW filter when device goes up, but it is
1070         * reserved in our case, so simply return.
1071         */
1072        if (!vid)
1073                return 0;
1074
1075        if (mlxsw_sp_port_vport_find(mlxsw_sp_port, vid))
1076                return 0;
1077
1078        mlxsw_sp_vport = mlxsw_sp_port_vport_create(mlxsw_sp_port, vid);
1079        if (!mlxsw_sp_vport)
1080                return -ENOMEM;
1081
1082        /* When adding the first VLAN interface on a bridged port we need to
1083         * transition all the active 802.1Q bridge VLANs to use explicit
1084         * {Port, VID} to FID mappings and set the port's mode to Virtual mode.
1085         */
1086        if (list_is_singular(&mlxsw_sp_port->vports_list)) {
1087                err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
1088                if (err)
1089                        goto err_port_vp_mode_trans;
1090        }
1091
1092        err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, true, untagged);
1093        if (err)
1094                goto err_port_add_vid;
1095
1096        return 0;
1097
1098err_port_add_vid:
1099        if (list_is_singular(&mlxsw_sp_port->vports_list))
1100                mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
1101err_port_vp_mode_trans:
1102        mlxsw_sp_port_vport_destroy(mlxsw_sp_vport);
1103        return err;
1104}
1105
1106static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1107                                  __be16 __always_unused proto, u16 vid)
1108{
1109        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1110        struct mlxsw_sp_port *mlxsw_sp_vport;
1111        struct mlxsw_sp_fid *f;
1112
1113        /* VLAN 0 is removed from HW filter when device goes down, but
1114         * it is reserved in our case, so simply return.
1115         */
1116        if (!vid)
1117                return 0;
1118
1119        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
1120        if (WARN_ON(!mlxsw_sp_vport))
1121                return 0;
1122
1123        mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false);
1124
1125        /* Drop FID reference. If this was the last reference the
1126         * resources will be freed.
1127         */
1128        f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
1129        if (f && !WARN_ON(!f->leave))
1130                f->leave(mlxsw_sp_vport);
1131
1132        /* When removing the last VLAN interface on a bridged port we need to
1133         * transition all active 802.1Q bridge VLANs to use VID to FID
1134         * mappings and set port's mode to VLAN mode.
1135         */
1136        if (list_is_singular(&mlxsw_sp_port->vports_list))
1137                mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
1138
1139        mlxsw_sp_port_vport_destroy(mlxsw_sp_vport);
1140
1141        return 0;
1142}
1143
1144static int mlxsw_sp_port_get_phys_port_name(struct net_device *dev, char *name,
1145                                            size_t len)
1146{
1147        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1148        u8 module = mlxsw_sp_port->mapping.module;
1149        u8 width = mlxsw_sp_port->mapping.width;
1150        u8 lane = mlxsw_sp_port->mapping.lane;
1151        int err;
1152
1153        if (!mlxsw_sp_port->split)
1154                err = snprintf(name, len, "p%d", module + 1);
1155        else
1156                err = snprintf(name, len, "p%ds%d", module + 1,
1157                               lane / width);
1158
1159        if (err >= len)
1160                return -EINVAL;
1161
1162        return 0;
1163}
1164
1165static struct mlxsw_sp_port_mall_tc_entry *
1166mlxsw_sp_port_mirror_entry_find(struct mlxsw_sp_port *port,
1167                                unsigned long cookie) {
1168        struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
1169
1170        list_for_each_entry(mall_tc_entry, &port->mall_tc_list, list)
1171                if (mall_tc_entry->cookie == cookie)
1172                        return mall_tc_entry;
1173
1174        return NULL;
1175}
1176
1177static int
1178mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
1179                                      struct tc_cls_matchall_offload *cls,
1180                                      const struct tc_action *a,
1181                                      bool ingress)
1182{
1183        struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
1184        struct net *net = dev_net(mlxsw_sp_port->dev);
1185        enum mlxsw_sp_span_type span_type;
1186        struct mlxsw_sp_port *to_port;
1187        struct net_device *to_dev;
1188        int ifindex;
1189        int err;
1190
1191        ifindex = tcf_mirred_ifindex(a);
1192        to_dev = __dev_get_by_index(net, ifindex);
1193        if (!to_dev) {
1194                netdev_err(mlxsw_sp_port->dev, "Could not find requested device\n");
1195                return -EINVAL;
1196        }
1197
1198        if (!mlxsw_sp_port_dev_check(to_dev)) {
1199                netdev_err(mlxsw_sp_port->dev, "Cannot mirror to a non-spectrum port");
1200                return -ENOTSUPP;
1201        }
1202        to_port = netdev_priv(to_dev);
1203
1204        mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL);
1205        if (!mall_tc_entry)
1206                return -ENOMEM;
1207
1208        mall_tc_entry->cookie = cls->cookie;
1209        mall_tc_entry->type = MLXSW_SP_PORT_MALL_MIRROR;
1210        mall_tc_entry->mirror.to_local_port = to_port->local_port;
1211        mall_tc_entry->mirror.ingress = ingress;
1212        list_add_tail(&mall_tc_entry->list, &mlxsw_sp_port->mall_tc_list);
1213
1214        span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
1215        err = mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_port, span_type);
1216        if (err)
1217                goto err_mirror_add;
1218        return 0;
1219
1220err_mirror_add:
1221        list_del(&mall_tc_entry->list);
1222        kfree(mall_tc_entry);
1223        return err;
1224}
1225
1226static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
1227                                          __be16 protocol,
1228                                          struct tc_cls_matchall_offload *cls,
1229                                          bool ingress)
1230{
1231        const struct tc_action *a;
1232        LIST_HEAD(actions);
1233        int err;
1234
1235        if (!tc_single_action(cls->exts)) {
1236                netdev_err(mlxsw_sp_port->dev, "only singular actions are supported\n");
1237                return -ENOTSUPP;
1238        }
1239
1240        tcf_exts_to_list(cls->exts, &actions);
1241        list_for_each_entry(a, &actions, list) {
1242                if (!is_tcf_mirred_mirror(a) || protocol != htons(ETH_P_ALL))
1243                        return -ENOTSUPP;
1244
1245                err = mlxsw_sp_port_add_cls_matchall_mirror(mlxsw_sp_port, cls,
1246                                                            a, ingress);
1247                if (err)
1248                        return err;
1249        }
1250
1251        return 0;
1252}
1253
1254static void mlxsw_sp_port_del_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
1255                                           struct tc_cls_matchall_offload *cls)
1256{
1257        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1258        struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
1259        enum mlxsw_sp_span_type span_type;
1260        struct mlxsw_sp_port *to_port;
1261
1262        mall_tc_entry = mlxsw_sp_port_mirror_entry_find(mlxsw_sp_port,
1263                                                        cls->cookie);
1264        if (!mall_tc_entry) {
1265                netdev_dbg(mlxsw_sp_port->dev, "tc entry not found on port\n");
1266                return;
1267        }
1268
1269        switch (mall_tc_entry->type) {
1270        case MLXSW_SP_PORT_MALL_MIRROR:
1271                to_port = mlxsw_sp->ports[mall_tc_entry->mirror.to_local_port];
1272                span_type = mall_tc_entry->mirror.ingress ?
1273                                MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
1274
1275                mlxsw_sp_span_mirror_remove(mlxsw_sp_port, to_port, span_type);
1276                break;
1277        default:
1278                WARN_ON(1);
1279        }
1280
1281        list_del(&mall_tc_entry->list);
1282        kfree(mall_tc_entry);
1283}
1284
1285static int mlxsw_sp_setup_tc(struct net_device *dev, u32 handle,
1286                             __be16 proto, struct tc_to_netdev *tc)
1287{
1288        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1289        bool ingress = TC_H_MAJ(handle) == TC_H_MAJ(TC_H_INGRESS);
1290
1291        if (tc->type == TC_SETUP_MATCHALL) {
1292                switch (tc->cls_mall->command) {
1293                case TC_CLSMATCHALL_REPLACE:
1294                        return mlxsw_sp_port_add_cls_matchall(mlxsw_sp_port,
1295                                                              proto,
1296                                                              tc->cls_mall,
1297                                                              ingress);
1298                case TC_CLSMATCHALL_DESTROY:
1299                        mlxsw_sp_port_del_cls_matchall(mlxsw_sp_port,
1300                                                       tc->cls_mall);
1301                        return 0;
1302                default:
1303                        return -EINVAL;
1304                }
1305        }
1306
1307        return -ENOTSUPP;
1308}
1309
1310static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
1311        .ndo_open               = mlxsw_sp_port_open,
1312        .ndo_stop               = mlxsw_sp_port_stop,
1313        .ndo_start_xmit         = mlxsw_sp_port_xmit,
1314        .ndo_setup_tc           = mlxsw_sp_setup_tc,
1315        .ndo_set_rx_mode        = mlxsw_sp_set_rx_mode,
1316        .ndo_set_mac_address    = mlxsw_sp_port_set_mac_address,
1317        .ndo_change_mtu         = mlxsw_sp_port_change_mtu,
1318        .ndo_get_stats64        = mlxsw_sp_port_get_stats64,
1319        .ndo_has_offload_stats  = mlxsw_sp_port_has_offload_stats,
1320        .ndo_get_offload_stats  = mlxsw_sp_port_get_offload_stats,
1321        .ndo_vlan_rx_add_vid    = mlxsw_sp_port_add_vid,
1322        .ndo_vlan_rx_kill_vid   = mlxsw_sp_port_kill_vid,
1323        .ndo_neigh_construct    = mlxsw_sp_router_neigh_construct,
1324        .ndo_neigh_destroy      = mlxsw_sp_router_neigh_destroy,
1325        .ndo_fdb_add            = switchdev_port_fdb_add,
1326        .ndo_fdb_del            = switchdev_port_fdb_del,
1327        .ndo_fdb_dump           = switchdev_port_fdb_dump,
1328        .ndo_bridge_setlink     = switchdev_port_bridge_setlink,
1329        .ndo_bridge_getlink     = switchdev_port_bridge_getlink,
1330        .ndo_bridge_dellink     = switchdev_port_bridge_dellink,
1331        .ndo_get_phys_port_name = mlxsw_sp_port_get_phys_port_name,
1332};
1333
1334static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
1335                                      struct ethtool_drvinfo *drvinfo)
1336{
1337        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1338        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1339
1340        strlcpy(drvinfo->driver, mlxsw_sp_driver_name, sizeof(drvinfo->driver));
1341        strlcpy(drvinfo->version, mlxsw_sp_driver_version,
1342                sizeof(drvinfo->version));
1343        snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
1344                 "%d.%d.%d",
1345                 mlxsw_sp->bus_info->fw_rev.major,
1346                 mlxsw_sp->bus_info->fw_rev.minor,
1347                 mlxsw_sp->bus_info->fw_rev.subminor);
1348        strlcpy(drvinfo->bus_info, mlxsw_sp->bus_info->device_name,
1349                sizeof(drvinfo->bus_info));
1350}
1351
1352static void mlxsw_sp_port_get_pauseparam(struct net_device *dev,
1353                                         struct ethtool_pauseparam *pause)
1354{
1355        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1356
1357        pause->rx_pause = mlxsw_sp_port->link.rx_pause;
1358        pause->tx_pause = mlxsw_sp_port->link.tx_pause;
1359}
1360
1361static int mlxsw_sp_port_pause_set(struct mlxsw_sp_port *mlxsw_sp_port,
1362                                   struct ethtool_pauseparam *pause)
1363{
1364        char pfcc_pl[MLXSW_REG_PFCC_LEN];
1365
1366        mlxsw_reg_pfcc_pack(pfcc_pl, mlxsw_sp_port->local_port);
1367        mlxsw_reg_pfcc_pprx_set(pfcc_pl, pause->rx_pause);
1368        mlxsw_reg_pfcc_pptx_set(pfcc_pl, pause->tx_pause);
1369
1370        return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pfcc),
1371                               pfcc_pl);
1372}
1373
1374static int mlxsw_sp_port_set_pauseparam(struct net_device *dev,
1375                                        struct ethtool_pauseparam *pause)
1376{
1377        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1378        bool pause_en = pause->tx_pause || pause->rx_pause;
1379        int err;
1380
1381        if (mlxsw_sp_port->dcb.pfc && mlxsw_sp_port->dcb.pfc->pfc_en) {
1382                netdev_err(dev, "PFC already enabled on port\n");
1383                return -EINVAL;
1384        }
1385
1386        if (pause->autoneg) {
1387                netdev_err(dev, "PAUSE frames autonegotiation isn't supported\n");
1388                return -EINVAL;
1389        }
1390
1391        err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
1392        if (err) {
1393                netdev_err(dev, "Failed to configure port's headroom\n");
1394                return err;
1395        }
1396
1397        err = mlxsw_sp_port_pause_set(mlxsw_sp_port, pause);
1398        if (err) {
1399                netdev_err(dev, "Failed to set PAUSE parameters\n");
1400                goto err_port_pause_configure;
1401        }
1402
1403        mlxsw_sp_port->link.rx_pause = pause->rx_pause;
1404        mlxsw_sp_port->link.tx_pause = pause->tx_pause;
1405
1406        return 0;
1407
1408err_port_pause_configure:
1409        pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
1410        mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
1411        return err;
1412}
1413
1414struct mlxsw_sp_port_hw_stats {
1415        char str[ETH_GSTRING_LEN];
1416        u64 (*getter)(char *payload);
1417};
1418
1419static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = {
1420        {
1421                .str = "a_frames_transmitted_ok",
1422                .getter = mlxsw_reg_ppcnt_a_frames_transmitted_ok_get,
1423        },
1424        {
1425                .str = "a_frames_received_ok",
1426                .getter = mlxsw_reg_ppcnt_a_frames_received_ok_get,
1427        },
1428        {
1429                .str = "a_frame_check_sequence_errors",
1430                .getter = mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get,
1431        },
1432        {
1433                .str = "a_alignment_errors",
1434                .getter = mlxsw_reg_ppcnt_a_alignment_errors_get,
1435        },
1436        {
1437                .str = "a_octets_transmitted_ok",
1438                .getter = mlxsw_reg_ppcnt_a_octets_transmitted_ok_get,
1439        },
1440        {
1441                .str = "a_octets_received_ok",
1442                .getter = mlxsw_reg_ppcnt_a_octets_received_ok_get,
1443        },
1444        {
1445                .str = "a_multicast_frames_xmitted_ok",
1446                .getter = mlxsw_reg_ppcnt_a_multicast_frames_xmitted_ok_get,
1447        },
1448        {
1449                .str = "a_broadcast_frames_xmitted_ok",
1450                .getter = mlxsw_reg_ppcnt_a_broadcast_frames_xmitted_ok_get,
1451        },
1452        {
1453                .str = "a_multicast_frames_received_ok",
1454                .getter = mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get,
1455        },
1456        {
1457                .str = "a_broadcast_frames_received_ok",
1458                .getter = mlxsw_reg_ppcnt_a_broadcast_frames_received_ok_get,
1459        },
1460        {
1461                .str = "a_in_range_length_errors",
1462                .getter = mlxsw_reg_ppcnt_a_in_range_length_errors_get,
1463        },
1464        {
1465                .str = "a_out_of_range_length_field",
1466                .getter = mlxsw_reg_ppcnt_a_out_of_range_length_field_get,
1467        },
1468        {
1469                .str = "a_frame_too_long_errors",
1470                .getter = mlxsw_reg_ppcnt_a_frame_too_long_errors_get,
1471        },
1472        {
1473                .str = "a_symbol_error_during_carrier",
1474                .getter = mlxsw_reg_ppcnt_a_symbol_error_during_carrier_get,
1475        },
1476        {
1477                .str = "a_mac_control_frames_transmitted",
1478                .getter = mlxsw_reg_ppcnt_a_mac_control_frames_transmitted_get,
1479        },
1480        {
1481                .str = "a_mac_control_frames_received",
1482                .getter = mlxsw_reg_ppcnt_a_mac_control_frames_received_get,
1483        },
1484        {
1485                .str = "a_unsupported_opcodes_received",
1486                .getter = mlxsw_reg_ppcnt_a_unsupported_opcodes_received_get,
1487        },
1488        {
1489                .str = "a_pause_mac_ctrl_frames_received",
1490                .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_received_get,
1491        },
1492        {
1493                .str = "a_pause_mac_ctrl_frames_xmitted",
1494                .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_transmitted_get,
1495        },
1496};
1497
1498#define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats)
1499
1500static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = {
1501        {
1502                .str = "rx_octets_prio",
1503                .getter = mlxsw_reg_ppcnt_rx_octets_get,
1504        },
1505        {
1506                .str = "rx_frames_prio",
1507                .getter = mlxsw_reg_ppcnt_rx_frames_get,
1508        },
1509        {
1510                .str = "tx_octets_prio",
1511                .getter = mlxsw_reg_ppcnt_tx_octets_get,
1512        },
1513        {
1514                .str = "tx_frames_prio",
1515                .getter = mlxsw_reg_ppcnt_tx_frames_get,
1516        },
1517        {
1518                .str = "rx_pause_prio",
1519                .getter = mlxsw_reg_ppcnt_rx_pause_get,
1520        },
1521        {
1522                .str = "rx_pause_duration_prio",
1523                .getter = mlxsw_reg_ppcnt_rx_pause_duration_get,
1524        },
1525        {
1526                .str = "tx_pause_prio",
1527                .getter = mlxsw_reg_ppcnt_tx_pause_get,
1528        },
1529        {
1530                .str = "tx_pause_duration_prio",
1531                .getter = mlxsw_reg_ppcnt_tx_pause_duration_get,
1532        },
1533};
1534
1535#define MLXSW_SP_PORT_HW_PRIO_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_prio_stats)
1536
1537static u64 mlxsw_reg_ppcnt_tc_transmit_queue_bytes_get(char *ppcnt_pl)
1538{
1539        u64 transmit_queue = mlxsw_reg_ppcnt_tc_transmit_queue_get(ppcnt_pl);
1540
1541        return MLXSW_SP_CELLS_TO_BYTES(transmit_queue);
1542}
1543
1544static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
1545        {
1546                .str = "tc_transmit_queue_tc",
1547                .getter = mlxsw_reg_ppcnt_tc_transmit_queue_bytes_get,
1548        },
1549        {
1550                .str = "tc_no_buffer_discard_uc_tc",
1551                .getter = mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get,
1552        },
1553};
1554
1555#define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats)
1556
1557#define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \
1558                                         (MLXSW_SP_PORT_HW_PRIO_STATS_LEN + \
1559                                          MLXSW_SP_PORT_HW_TC_STATS_LEN) * \
1560                                         IEEE_8021QAZ_MAX_TCS)
1561
1562static void mlxsw_sp_port_get_prio_strings(u8 **p, int prio)
1563{
1564        int i;
1565
1566        for (i = 0; i < MLXSW_SP_PORT_HW_PRIO_STATS_LEN; i++) {
1567                snprintf(*p, ETH_GSTRING_LEN, "%s_%d",
1568                         mlxsw_sp_port_hw_prio_stats[i].str, prio);
1569                *p += ETH_GSTRING_LEN;
1570        }
1571}
1572
1573static void mlxsw_sp_port_get_tc_strings(u8 **p, int tc)
1574{
1575        int i;
1576
1577        for (i = 0; i < MLXSW_SP_PORT_HW_TC_STATS_LEN; i++) {
1578                snprintf(*p, ETH_GSTRING_LEN, "%s_%d",
1579                         mlxsw_sp_port_hw_tc_stats[i].str, tc);
1580                *p += ETH_GSTRING_LEN;
1581        }
1582}
1583
1584static void mlxsw_sp_port_get_strings(struct net_device *dev,
1585                                      u32 stringset, u8 *data)
1586{
1587        u8 *p = data;
1588        int i;
1589
1590        switch (stringset) {
1591        case ETH_SS_STATS:
1592                for (i = 0; i < MLXSW_SP_PORT_HW_STATS_LEN; i++) {
1593                        memcpy(p, mlxsw_sp_port_hw_stats[i].str,
1594                               ETH_GSTRING_LEN);
1595                        p += ETH_GSTRING_LEN;
1596                }
1597
1598                for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
1599                        mlxsw_sp_port_get_prio_strings(&p, i);
1600
1601                for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
1602                        mlxsw_sp_port_get_tc_strings(&p, i);
1603
1604                break;
1605        }
1606}
1607
1608static int mlxsw_sp_port_set_phys_id(struct net_device *dev,
1609                                     enum ethtool_phys_id_state state)
1610{
1611        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1612        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1613        char mlcr_pl[MLXSW_REG_MLCR_LEN];
1614        bool active;
1615
1616        switch (state) {
1617        case ETHTOOL_ID_ACTIVE:
1618                active = true;
1619                break;
1620        case ETHTOOL_ID_INACTIVE:
1621                active = false;
1622                break;
1623        default:
1624                return -EOPNOTSUPP;
1625        }
1626
1627        mlxsw_reg_mlcr_pack(mlcr_pl, mlxsw_sp_port->local_port, active);
1628        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mlcr), mlcr_pl);
1629}
1630
1631static int
1632mlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats,
1633                               int *p_len, enum mlxsw_reg_ppcnt_grp grp)
1634{
1635        switch (grp) {
1636        case  MLXSW_REG_PPCNT_IEEE_8023_CNT:
1637                *p_hw_stats = mlxsw_sp_port_hw_stats;
1638                *p_len = MLXSW_SP_PORT_HW_STATS_LEN;
1639                break;
1640        case MLXSW_REG_PPCNT_PRIO_CNT:
1641                *p_hw_stats = mlxsw_sp_port_hw_prio_stats;
1642                *p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
1643                break;
1644        case MLXSW_REG_PPCNT_TC_CNT:
1645                *p_hw_stats = mlxsw_sp_port_hw_tc_stats;
1646                *p_len = MLXSW_SP_PORT_HW_TC_STATS_LEN;
1647                break;
1648        default:
1649                WARN_ON(1);
1650                return -ENOTSUPP;
1651        }
1652        return 0;
1653}
1654
1655static void __mlxsw_sp_port_get_stats(struct net_device *dev,
1656                                      enum mlxsw_reg_ppcnt_grp grp, int prio,
1657                                      u64 *data, int data_index)
1658{
1659        struct mlxsw_sp_port_hw_stats *hw_stats;
1660        char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
1661        int i, len;
1662        int err;
1663
1664        err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp);
1665        if (err)
1666                return;
1667        mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl);
1668        for (i = 0; i < len; i++)
1669                data[data_index + i] = hw_stats[i].getter(ppcnt_pl);
1670}
1671
1672static void mlxsw_sp_port_get_stats(struct net_device *dev,
1673                                    struct ethtool_stats *stats, u64 *data)
1674{
1675        int i, data_index = 0;
1676
1677        /* IEEE 802.3 Counters */
1678        __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_IEEE_8023_CNT, 0,
1679                                  data, data_index);
1680        data_index = MLXSW_SP_PORT_HW_STATS_LEN;
1681
1682        /* Per-Priority Counters */
1683        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1684                __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_PRIO_CNT, i,
1685                                          data, data_index);
1686                data_index += MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
1687        }
1688
1689        /* Per-TC Counters */
1690        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1691                __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_TC_CNT, i,
1692                                          data, data_index);
1693                data_index += MLXSW_SP_PORT_HW_TC_STATS_LEN;
1694        }
1695}
1696
1697static int mlxsw_sp_port_get_sset_count(struct net_device *dev, int sset)
1698{
1699        switch (sset) {
1700        case ETH_SS_STATS:
1701                return MLXSW_SP_PORT_ETHTOOL_STATS_LEN;
1702        default:
1703                return -EOPNOTSUPP;
1704        }
1705}
1706
1707struct mlxsw_sp_port_link_mode {
1708        enum ethtool_link_mode_bit_indices mask_ethtool;
1709        u32 mask;
1710        u32 speed;
1711};
1712
1713static const struct mlxsw_sp_port_link_mode mlxsw_sp_port_link_mode[] = {
1714        {
1715                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100BASE_T,
1716                .mask_ethtool   = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
1717                .speed          = SPEED_100,
1718        },
1719        {
1720                .mask           = MLXSW_REG_PTYS_ETH_SPEED_SGMII |
1721                                  MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX,
1722                .mask_ethtool   = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
1723                .speed          = SPEED_1000,
1724        },
1725        {
1726                .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_T,
1727                .mask_ethtool   = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
1728                .speed          = SPEED_10000,
1729        },
1730        {
1731                .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 |
1732                                  MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4,
1733                .mask_ethtool   = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
1734                .speed          = SPEED_10000,
1735        },
1736        {
1737                .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
1738                                  MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
1739                                  MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
1740                                  MLXSW_REG_PTYS_ETH_SPEED_10GBASE_ER_LR,
1741                .mask_ethtool   = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
1742                .speed          = SPEED_10000,
1743        },
1744        {
1745                .mask           = MLXSW_REG_PTYS_ETH_SPEED_20GBASE_KR2,
1746                .mask_ethtool   = ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
1747                .speed          = SPEED_20000,
1748        },
1749        {
1750                .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4,
1751                .mask_ethtool   = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
1752                .speed          = SPEED_40000,
1753        },
1754        {
1755                .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4,
1756                .mask_ethtool   = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
1757                .speed          = SPEED_40000,
1758        },
1759        {
1760                .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4,
1761                .mask_ethtool   = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
1762                .speed          = SPEED_40000,
1763        },
1764        {
1765                .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_LR4_ER4,
1766                .mask_ethtool   = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
1767                .speed          = SPEED_40000,
1768        },
1769        {
1770                .mask           = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR,
1771                .mask_ethtool   = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
1772                .speed          = SPEED_25000,
1773        },
1774        {
1775                .mask           = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR,
1776                .mask_ethtool   = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
1777                .speed          = SPEED_25000,
1778        },
1779        {
1780                .mask           = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR,
1781                .mask_ethtool   = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
1782                .speed          = SPEED_25000,
1783        },
1784        {
1785                .mask           = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR,
1786                .mask_ethtool   = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
1787                .speed          = SPEED_25000,
1788        },
1789        {
1790                .mask           = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_CR2,
1791                .mask_ethtool   = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
1792                .speed          = SPEED_50000,
1793        },
1794        {
1795                .mask           = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR2,
1796                .mask_ethtool   = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
1797                .speed          = SPEED_50000,
1798        },
1799        {
1800                .mask           = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_SR2,
1801                .mask_ethtool   = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
1802                .speed          = SPEED_50000,
1803        },
1804        {
1805                .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
1806                .mask_ethtool   = ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT,
1807                .speed          = SPEED_56000,
1808        },
1809        {
1810                .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
1811                .mask_ethtool   = ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT,
1812                .speed          = SPEED_56000,
1813        },
1814        {
1815                .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
1816                .mask_ethtool   = ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT,
1817                .speed          = SPEED_56000,
1818        },
1819        {
1820                .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
1821                .mask_ethtool   = ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
1822                .speed          = SPEED_56000,
1823        },
1824        {
1825                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4,
1826                .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
1827                .speed          = SPEED_100000,
1828        },
1829        {
1830                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4,
1831                .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
1832                .speed          = SPEED_100000,
1833        },
1834        {
1835                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4,
1836                .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
1837                .speed          = SPEED_100000,
1838        },
1839        {
1840                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4,
1841                .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
1842                .speed          = SPEED_100000,
1843        },
1844};
1845
1846#define MLXSW_SP_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp_port_link_mode)
1847
1848static void
1849mlxsw_sp_from_ptys_supported_port(u32 ptys_eth_proto,
1850                                  struct ethtool_link_ksettings *cmd)
1851{
1852        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
1853                              MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
1854                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 |
1855                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 |
1856                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
1857                              MLXSW_REG_PTYS_ETH_SPEED_SGMII))
1858                ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
1859
1860        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
1861                              MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 |
1862                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 |
1863                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 |
1864                              MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX))
1865                ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane);
1866}
1867
1868static void mlxsw_sp_from_ptys_link(u32 ptys_eth_proto, unsigned long *mode)
1869{
1870        int i;
1871
1872        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1873                if (ptys_eth_proto & mlxsw_sp_port_link_mode[i].mask)
1874                        __set_bit(mlxsw_sp_port_link_mode[i].mask_ethtool,
1875                                  mode);
1876        }
1877}
1878
1879static void mlxsw_sp_from_ptys_speed_duplex(bool carrier_ok, u32 ptys_eth_proto,
1880                                            struct ethtool_link_ksettings *cmd)
1881{
1882        u32 speed = SPEED_UNKNOWN;
1883        u8 duplex = DUPLEX_UNKNOWN;
1884        int i;
1885
1886        if (!carrier_ok)
1887                goto out;
1888
1889        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1890                if (ptys_eth_proto & mlxsw_sp_port_link_mode[i].mask) {
1891                        speed = mlxsw_sp_port_link_mode[i].speed;
1892                        duplex = DUPLEX_FULL;
1893                        break;
1894                }
1895        }
1896out:
1897        cmd->base.speed = speed;
1898        cmd->base.duplex = duplex;
1899}
1900
1901static u8 mlxsw_sp_port_connector_port(u32 ptys_eth_proto)
1902{
1903        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
1904                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 |
1905                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
1906                              MLXSW_REG_PTYS_ETH_SPEED_SGMII))
1907                return PORT_FIBRE;
1908
1909        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
1910                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 |
1911                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4))
1912                return PORT_DA;
1913
1914        if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
1915                              MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 |
1916                              MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 |
1917                              MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4))
1918                return PORT_NONE;
1919
1920        return PORT_OTHER;
1921}
1922
1923static u32
1924mlxsw_sp_to_ptys_advert_link(const struct ethtool_link_ksettings *cmd)
1925{
1926        u32 ptys_proto = 0;
1927        int i;
1928
1929        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1930                if (test_bit(mlxsw_sp_port_link_mode[i].mask_ethtool,
1931                             cmd->link_modes.advertising))
1932                        ptys_proto |= mlxsw_sp_port_link_mode[i].mask;
1933        }
1934        return ptys_proto;
1935}
1936
1937static u32 mlxsw_sp_to_ptys_speed(u32 speed)
1938{
1939        u32 ptys_proto = 0;
1940        int i;
1941
1942        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1943                if (speed == mlxsw_sp_port_link_mode[i].speed)
1944                        ptys_proto |= mlxsw_sp_port_link_mode[i].mask;
1945        }
1946        return ptys_proto;
1947}
1948
1949static u32 mlxsw_sp_to_ptys_upper_speed(u32 upper_speed)
1950{
1951        u32 ptys_proto = 0;
1952        int i;
1953
1954        for (i = 0; i < MLXSW_SP_PORT_LINK_MODE_LEN; i++) {
1955                if (mlxsw_sp_port_link_mode[i].speed <= upper_speed)
1956                        ptys_proto |= mlxsw_sp_port_link_mode[i].mask;
1957        }
1958        return ptys_proto;
1959}
1960
1961static void mlxsw_sp_port_get_link_supported(u32 eth_proto_cap,
1962                                             struct ethtool_link_ksettings *cmd)
1963{
1964        ethtool_link_ksettings_add_link_mode(cmd, supported, Asym_Pause);
1965        ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
1966        ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
1967
1968        mlxsw_sp_from_ptys_supported_port(eth_proto_cap, cmd);
1969        mlxsw_sp_from_ptys_link(eth_proto_cap, cmd->link_modes.supported);
1970}
1971
1972static void mlxsw_sp_port_get_link_advertise(u32 eth_proto_admin, bool autoneg,
1973                                             struct ethtool_link_ksettings *cmd)
1974{
1975        if (!autoneg)
1976                return;
1977
1978        ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
1979        mlxsw_sp_from_ptys_link(eth_proto_admin, cmd->link_modes.advertising);
1980}
1981
1982static void
1983mlxsw_sp_port_get_link_lp_advertise(u32 eth_proto_lp, u8 autoneg_status,
1984                                    struct ethtool_link_ksettings *cmd)
1985{
1986        if (autoneg_status != MLXSW_REG_PTYS_AN_STATUS_OK || !eth_proto_lp)
1987                return;
1988
1989        ethtool_link_ksettings_add_link_mode(cmd, lp_advertising, Autoneg);
1990        mlxsw_sp_from_ptys_link(eth_proto_lp, cmd->link_modes.lp_advertising);
1991}
1992
1993static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
1994                                            struct ethtool_link_ksettings *cmd)
1995{
1996        u32 eth_proto_cap, eth_proto_admin, eth_proto_oper, eth_proto_lp;
1997        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1998        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1999        char ptys_pl[MLXSW_REG_PTYS_LEN];
2000        u8 autoneg_status;
2001        bool autoneg;
2002        int err;
2003
2004        autoneg = mlxsw_sp_port->link.autoneg;
2005        mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port, 0);
2006        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2007        if (err)
2008                return err;
2009        mlxsw_reg_ptys_unpack(ptys_pl, &eth_proto_cap, &eth_proto_admin,
2010                              &eth_proto_oper);
2011
2012        mlxsw_sp_port_get_link_supported(eth_proto_cap, cmd);
2013
2014        mlxsw_sp_port_get_link_advertise(eth_proto_admin, autoneg, cmd);
2015
2016        eth_proto_lp = mlxsw_reg_ptys_eth_proto_lp_advertise_get(ptys_pl);
2017        autoneg_status = mlxsw_reg_ptys_an_status_get(ptys_pl);
2018        mlxsw_sp_port_get_link_lp_advertise(eth_proto_lp, autoneg_status, cmd);
2019
2020        cmd->base.autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
2021        cmd->base.port = mlxsw_sp_port_connector_port(eth_proto_oper);
2022        mlxsw_sp_from_ptys_speed_duplex(netif_carrier_ok(dev), eth_proto_oper,
2023                                        cmd);
2024
2025        return 0;
2026}
2027
2028static int
2029mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
2030                                 const struct ethtool_link_ksettings *cmd)
2031{
2032        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
2033        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2034        char ptys_pl[MLXSW_REG_PTYS_LEN];
2035        u32 eth_proto_cap, eth_proto_new;
2036        bool autoneg;
2037        int err;
2038
2039        mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port, 0);
2040        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2041        if (err)
2042                return err;
2043        mlxsw_reg_ptys_unpack(ptys_pl, &eth_proto_cap, NULL, NULL);
2044
2045        autoneg = cmd->base.autoneg == AUTONEG_ENABLE;
2046        eth_proto_new = autoneg ?
2047                mlxsw_sp_to_ptys_advert_link(cmd) :
2048                mlxsw_sp_to_ptys_speed(cmd->base.speed);
2049
2050        eth_proto_new = eth_proto_new & eth_proto_cap;
2051        if (!eth_proto_new) {
2052                netdev_err(dev, "No supported speed requested\n");
2053                return -EINVAL;
2054        }
2055
2056        mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port, eth_proto_new);
2057        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2058        if (err)
2059                return err;
2060
2061        if (!netif_running(dev))
2062                return 0;
2063
2064        mlxsw_sp_port->link.autoneg = autoneg;
2065
2066        mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
2067        mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
2068
2069        return 0;
2070}
2071
2072static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
2073        .get_drvinfo            = mlxsw_sp_port_get_drvinfo,
2074        .get_link               = ethtool_op_get_link,
2075        .get_pauseparam         = mlxsw_sp_port_get_pauseparam,
2076        .set_pauseparam         = mlxsw_sp_port_set_pauseparam,
2077        .get_strings            = mlxsw_sp_port_get_strings,
2078        .set_phys_id            = mlxsw_sp_port_set_phys_id,
2079        .get_ethtool_stats      = mlxsw_sp_port_get_stats,
2080        .get_sset_count         = mlxsw_sp_port_get_sset_count,
2081        .get_link_ksettings     = mlxsw_sp_port_get_link_ksettings,
2082        .set_link_ksettings     = mlxsw_sp_port_set_link_ksettings,
2083};
2084
2085static int
2086mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 width)
2087{
2088        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2089        u32 upper_speed = MLXSW_SP_PORT_BASE_SPEED * width;
2090        char ptys_pl[MLXSW_REG_PTYS_LEN];
2091        u32 eth_proto_admin;
2092
2093        eth_proto_admin = mlxsw_sp_to_ptys_upper_speed(upper_speed);
2094        mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port,
2095                            eth_proto_admin);
2096        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2097}
2098
2099int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
2100                          enum mlxsw_reg_qeec_hr hr, u8 index, u8 next_index,
2101                          bool dwrr, u8 dwrr_weight)
2102{
2103        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2104        char qeec_pl[MLXSW_REG_QEEC_LEN];
2105
2106        mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
2107                            next_index);
2108        mlxsw_reg_qeec_de_set(qeec_pl, true);
2109        mlxsw_reg_qeec_dwrr_set(qeec_pl, dwrr);
2110        mlxsw_reg_qeec_dwrr_weight_set(qeec_pl, dwrr_weight);
2111        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
2112}
2113
2114int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
2115                                  enum mlxsw_reg_qeec_hr hr, u8 index,
2116                                  u8 next_index, u32 maxrate)
2117{
2118        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2119        char qeec_pl[MLXSW_REG_QEEC_LEN];
2120
2121        mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
2122                            next_index);
2123        mlxsw_reg_qeec_mase_set(qeec_pl, true);
2124        mlxsw_reg_qeec_max_shaper_rate_set(qeec_pl, maxrate);
2125        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
2126}
2127
2128int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port,
2129                              u8 switch_prio, u8 tclass)
2130{
2131        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2132        char qtct_pl[MLXSW_REG_QTCT_LEN];
2133
2134        mlxsw_reg_qtct_pack(qtct_pl, mlxsw_sp_port->local_port, switch_prio,
2135                            tclass);
2136        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtct), qtct_pl);
2137}
2138
2139static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
2140{
2141        int err, i;
2142
2143        /* Setup the elements hierarcy, so that each TC is linked to
2144         * one subgroup, which are all member in the same group.
2145         */
2146        err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
2147                                    MLXSW_REG_QEEC_HIERARCY_GROUP, 0, 0, false,
2148                                    0);
2149        if (err)
2150                return err;
2151        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
2152                err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
2153                                            MLXSW_REG_QEEC_HIERARCY_SUBGROUP, i,
2154                                            0, false, 0);
2155                if (err)
2156                        return err;
2157        }
2158        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
2159                err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
2160                                            MLXSW_REG_QEEC_HIERARCY_TC, i, i,
2161                                            false, 0);
2162                if (err)
2163                        return err;
2164        }
2165
2166        /* Make sure the max shaper is disabled in all hierarcies that
2167         * support it.
2168         */
2169        err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
2170                                            MLXSW_REG_QEEC_HIERARCY_PORT, 0, 0,
2171                                            MLXSW_REG_QEEC_MAS_DIS);
2172        if (err)
2173                return err;
2174        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
2175                err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
2176                                                    MLXSW_REG_QEEC_HIERARCY_SUBGROUP,
2177                                                    i, 0,
2178                                                    MLXSW_REG_QEEC_MAS_DIS);
2179                if (err)
2180                        return err;
2181        }
2182        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
2183                err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
2184                                                    MLXSW_REG_QEEC_HIERARCY_TC,
2185                                                    i, i,
2186                                                    MLXSW_REG_QEEC_MAS_DIS);
2187                if (err)
2188                        return err;
2189        }
2190
2191        /* Map all priorities to traffic class 0. */
2192        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
2193                err = mlxsw_sp_port_prio_tc_set(mlxsw_sp_port, i, 0);
2194                if (err)
2195                        return err;
2196        }
2197
2198        return 0;
2199}
2200
2201static int mlxsw_sp_port_pvid_vport_create(struct mlxsw_sp_port *mlxsw_sp_port)
2202{
2203        mlxsw_sp_port->pvid = 1;
2204
2205        return mlxsw_sp_port_add_vid(mlxsw_sp_port->dev, 0, 1);
2206}
2207
2208static int mlxsw_sp_port_pvid_vport_destroy(struct mlxsw_sp_port *mlxsw_sp_port)
2209{
2210        return mlxsw_sp_port_kill_vid(mlxsw_sp_port->dev, 0, 1);
2211}
2212
2213static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2214                                bool split, u8 module, u8 width, u8 lane)
2215{
2216        struct mlxsw_sp_port *mlxsw_sp_port;
2217        struct net_device *dev;
2218        size_t bytes;
2219        int err;
2220
2221        dev = alloc_etherdev(sizeof(struct mlxsw_sp_port));
2222        if (!dev)
2223                return -ENOMEM;
2224        mlxsw_sp_port = netdev_priv(dev);
2225        mlxsw_sp_port->dev = dev;
2226        mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
2227        mlxsw_sp_port->local_port = local_port;
2228        mlxsw_sp_port->split = split;
2229        mlxsw_sp_port->mapping.module = module;
2230        mlxsw_sp_port->mapping.width = width;
2231        mlxsw_sp_port->mapping.lane = lane;
2232        mlxsw_sp_port->link.autoneg = 1;
2233        bytes = DIV_ROUND_UP(VLAN_N_VID, BITS_PER_BYTE);
2234        mlxsw_sp_port->active_vlans = kzalloc(bytes, GFP_KERNEL);
2235        if (!mlxsw_sp_port->active_vlans) {
2236                err = -ENOMEM;
2237                goto err_port_active_vlans_alloc;
2238        }
2239        mlxsw_sp_port->untagged_vlans = kzalloc(bytes, GFP_KERNEL);
2240        if (!mlxsw_sp_port->untagged_vlans) {
2241                err = -ENOMEM;
2242                goto err_port_untagged_vlans_alloc;
2243        }
2244        INIT_LIST_HEAD(&mlxsw_sp_port->vports_list);
2245        INIT_LIST_HEAD(&mlxsw_sp_port->mall_tc_list);
2246
2247        mlxsw_sp_port->pcpu_stats =
2248                netdev_alloc_pcpu_stats(struct mlxsw_sp_port_pcpu_stats);
2249        if (!mlxsw_sp_port->pcpu_stats) {
2250                err = -ENOMEM;
2251                goto err_alloc_stats;
2252        }
2253
2254        mlxsw_sp_port->hw_stats.cache =
2255                kzalloc(sizeof(*mlxsw_sp_port->hw_stats.cache), GFP_KERNEL);
2256
2257        if (!mlxsw_sp_port->hw_stats.cache) {
2258                err = -ENOMEM;
2259                goto err_alloc_hw_stats;
2260        }
2261        INIT_DELAYED_WORK(&mlxsw_sp_port->hw_stats.update_dw,
2262                          &update_stats_cache);
2263
2264        dev->netdev_ops = &mlxsw_sp_port_netdev_ops;
2265        dev->ethtool_ops = &mlxsw_sp_port_ethtool_ops;
2266
2267        err = mlxsw_sp_port_swid_set(mlxsw_sp_port, 0);
2268        if (err) {
2269                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set SWID\n",
2270                        mlxsw_sp_port->local_port);
2271                goto err_port_swid_set;
2272        }
2273
2274        err = mlxsw_sp_port_dev_addr_init(mlxsw_sp_port);
2275        if (err) {
2276                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unable to init port mac address\n",
2277                        mlxsw_sp_port->local_port);
2278                goto err_dev_addr_init;
2279        }
2280
2281        netif_carrier_off(dev);
2282
2283        dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_LLTX | NETIF_F_SG |
2284                         NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
2285        dev->hw_features |= NETIF_F_HW_TC;
2286
2287        /* Each packet needs to have a Tx header (metadata) on top all other
2288         * headers.
2289         */
2290        dev->needed_headroom = MLXSW_TXHDR_LEN;
2291
2292        err = mlxsw_sp_port_system_port_mapping_set(mlxsw_sp_port);
2293        if (err) {
2294                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set system port mapping\n",
2295                        mlxsw_sp_port->local_port);
2296                goto err_port_system_port_mapping_set;
2297        }
2298
2299        err = mlxsw_sp_port_speed_by_width_set(mlxsw_sp_port, width);
2300        if (err) {
2301                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to enable speeds\n",
2302                        mlxsw_sp_port->local_port);
2303                goto err_port_speed_by_width_set;
2304        }
2305
2306        err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, ETH_DATA_LEN);
2307        if (err) {
2308                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set MTU\n",
2309                        mlxsw_sp_port->local_port);
2310                goto err_port_mtu_set;
2311        }
2312
2313        err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
2314        if (err)
2315                goto err_port_admin_status_set;
2316
2317        err = mlxsw_sp_port_buffers_init(mlxsw_sp_port);
2318        if (err) {
2319                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize buffers\n",
2320                        mlxsw_sp_port->local_port);
2321                goto err_port_buffers_init;
2322        }
2323
2324        err = mlxsw_sp_port_ets_init(mlxsw_sp_port);
2325        if (err) {
2326                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize ETS\n",
2327                        mlxsw_sp_port->local_port);
2328                goto err_port_ets_init;
2329        }
2330
2331        /* ETS and buffers must be initialized before DCB. */
2332        err = mlxsw_sp_port_dcb_init(mlxsw_sp_port);
2333        if (err) {
2334                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize DCB\n",
2335                        mlxsw_sp_port->local_port);
2336                goto err_port_dcb_init;
2337        }
2338
2339        err = mlxsw_sp_port_pvid_vport_create(mlxsw_sp_port);
2340        if (err) {
2341                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to create PVID vPort\n",
2342                        mlxsw_sp_port->local_port);
2343                goto err_port_pvid_vport_create;
2344        }
2345
2346        mlxsw_sp_port_switchdev_init(mlxsw_sp_port);
2347        mlxsw_sp->ports[local_port] = mlxsw_sp_port;
2348        err = register_netdev(dev);
2349        if (err) {
2350                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to register netdev\n",
2351                        mlxsw_sp_port->local_port);
2352                goto err_register_netdev;
2353        }
2354
2355        err = mlxsw_core_port_init(mlxsw_sp->core, &mlxsw_sp_port->core_port,
2356                                   mlxsw_sp_port->local_port, dev,
2357                                   mlxsw_sp_port->split, module);
2358        if (err) {
2359                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to init core port\n",
2360                        mlxsw_sp_port->local_port);
2361                goto err_core_port_init;
2362        }
2363
2364        mlxsw_core_schedule_dw(&mlxsw_sp_port->hw_stats.update_dw, 0);
2365        return 0;
2366
2367err_core_port_init:
2368        unregister_netdev(dev);
2369err_register_netdev:
2370        mlxsw_sp->ports[local_port] = NULL;
2371        mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
2372        mlxsw_sp_port_pvid_vport_destroy(mlxsw_sp_port);
2373err_port_pvid_vport_create:
2374        mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
2375err_port_dcb_init:
2376err_port_ets_init:
2377err_port_buffers_init:
2378err_port_admin_status_set:
2379err_port_mtu_set:
2380err_port_speed_by_width_set:
2381err_port_system_port_mapping_set:
2382err_dev_addr_init:
2383        mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
2384err_port_swid_set:
2385        kfree(mlxsw_sp_port->hw_stats.cache);
2386err_alloc_hw_stats:
2387        free_percpu(mlxsw_sp_port->pcpu_stats);
2388err_alloc_stats:
2389        kfree(mlxsw_sp_port->untagged_vlans);
2390err_port_untagged_vlans_alloc:
2391        kfree(mlxsw_sp_port->active_vlans);
2392err_port_active_vlans_alloc:
2393        free_netdev(dev);
2394        return err;
2395}
2396
2397static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
2398{
2399        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
2400
2401        if (!mlxsw_sp_port)
2402                return;
2403        cancel_delayed_work_sync(&mlxsw_sp_port->hw_stats.update_dw);
2404        mlxsw_core_port_fini(&mlxsw_sp_port->core_port);
2405        unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
2406        mlxsw_sp->ports[local_port] = NULL;
2407        mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
2408        mlxsw_sp_port_pvid_vport_destroy(mlxsw_sp_port);
2409        mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
2410        mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
2411        mlxsw_sp_port_module_unmap(mlxsw_sp, mlxsw_sp_port->local_port);
2412        free_percpu(mlxsw_sp_port->pcpu_stats);
2413        kfree(mlxsw_sp_port->hw_stats.cache);
2414        kfree(mlxsw_sp_port->untagged_vlans);
2415        kfree(mlxsw_sp_port->active_vlans);
2416        WARN_ON_ONCE(!list_empty(&mlxsw_sp_port->vports_list));
2417        free_netdev(mlxsw_sp_port->dev);
2418}
2419
2420static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
2421{
2422        int i;
2423
2424        for (i = 1; i < MLXSW_PORT_MAX_PORTS; i++)
2425                mlxsw_sp_port_remove(mlxsw_sp, i);
2426        kfree(mlxsw_sp->ports);
2427}
2428
2429static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
2430{
2431        u8 module, width, lane;
2432        size_t alloc_size;
2433        int i;
2434        int err;
2435
2436        alloc_size = sizeof(struct mlxsw_sp_port *) * MLXSW_PORT_MAX_PORTS;
2437        mlxsw_sp->ports = kzalloc(alloc_size, GFP_KERNEL);
2438        if (!mlxsw_sp->ports)
2439                return -ENOMEM;
2440
2441        for (i = 1; i < MLXSW_PORT_MAX_PORTS; i++) {
2442                err = mlxsw_sp_port_module_info_get(mlxsw_sp, i, &module,
2443                                                    &width, &lane);
2444                if (err)
2445                        goto err_port_module_info_get;
2446                if (!width)
2447                        continue;
2448                mlxsw_sp->port_to_module[i] = module;
2449                err = mlxsw_sp_port_create(mlxsw_sp, i, false, module, width,
2450                                           lane);
2451                if (err)
2452                        goto err_port_create;
2453        }
2454        return 0;
2455
2456err_port_create:
2457err_port_module_info_get:
2458        for (i--; i >= 1; i--)
2459                mlxsw_sp_port_remove(mlxsw_sp, i);
2460        kfree(mlxsw_sp->ports);
2461        return err;
2462}
2463
2464static u8 mlxsw_sp_cluster_base_port_get(u8 local_port)
2465{
2466        u8 offset = (local_port - 1) % MLXSW_SP_PORTS_PER_CLUSTER_MAX;
2467
2468        return local_port - offset;
2469}
2470
2471static int mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp, u8 base_port,
2472                                      u8 module, unsigned int count)
2473{
2474        u8 width = MLXSW_PORT_MODULE_MAX_WIDTH / count;
2475        int err, i;
2476
2477        for (i = 0; i < count; i++) {
2478                err = mlxsw_sp_port_module_map(mlxsw_sp, base_port + i, module,
2479                                               width, i * width);
2480                if (err)
2481                        goto err_port_module_map;
2482        }
2483
2484        for (i = 0; i < count; i++) {
2485                err = __mlxsw_sp_port_swid_set(mlxsw_sp, base_port + i, 0);
2486                if (err)
2487                        goto err_port_swid_set;
2488        }
2489
2490        for (i = 0; i < count; i++) {
2491                err = mlxsw_sp_port_create(mlxsw_sp, base_port + i, true,
2492                                           module, width, i * width);
2493                if (err)
2494                        goto err_port_create;
2495        }
2496
2497        return 0;
2498
2499err_port_create:
2500        for (i--; i >= 0; i--)
2501                mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
2502        i = count;
2503err_port_swid_set:
2504        for (i--; i >= 0; i--)
2505                __mlxsw_sp_port_swid_set(mlxsw_sp, base_port + i,
2506                                         MLXSW_PORT_SWID_DISABLED_PORT);
2507        i = count;
2508err_port_module_map:
2509        for (i--; i >= 0; i--)
2510                mlxsw_sp_port_module_unmap(mlxsw_sp, base_port + i);
2511        return err;
2512}
2513
2514static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp,
2515                                         u8 base_port, unsigned int count)
2516{
2517        u8 local_port, module, width = MLXSW_PORT_MODULE_MAX_WIDTH;
2518        int i;
2519
2520        /* Split by four means we need to re-create two ports, otherwise
2521         * only one.
2522         */
2523        count = count / 2;
2524
2525        for (i = 0; i < count; i++) {
2526                local_port = base_port + i * 2;
2527                module = mlxsw_sp->port_to_module[local_port];
2528
2529                mlxsw_sp_port_module_map(mlxsw_sp, local_port, module, width,
2530                                         0);
2531        }
2532
2533        for (i = 0; i < count; i++)
2534                __mlxsw_sp_port_swid_set(mlxsw_sp, base_port + i * 2, 0);
2535
2536        for (i = 0; i < count; i++) {
2537                local_port = base_port + i * 2;
2538                module = mlxsw_sp->port_to_module[local_port];
2539
2540                mlxsw_sp_port_create(mlxsw_sp, local_port, false, module,
2541                                     width, 0);
2542        }
2543}
2544
2545static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
2546                               unsigned int count)
2547{
2548        struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2549        struct mlxsw_sp_port *mlxsw_sp_port;
2550        u8 module, cur_width, base_port;
2551        int i;
2552        int err;
2553
2554        mlxsw_sp_port = mlxsw_sp->ports[local_port];
2555        if (!mlxsw_sp_port) {
2556                dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
2557                        local_port);
2558                return -EINVAL;
2559        }
2560
2561        module = mlxsw_sp_port->mapping.module;
2562        cur_width = mlxsw_sp_port->mapping.width;
2563
2564        if (count != 2 && count != 4) {
2565                netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n");
2566                return -EINVAL;
2567        }
2568
2569        if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) {
2570                netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
2571                return -EINVAL;
2572        }
2573
2574        /* Make sure we have enough slave (even) ports for the split. */
2575        if (count == 2) {
2576                base_port = local_port;
2577                if (mlxsw_sp->ports[base_port + 1]) {
2578                        netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
2579                        return -EINVAL;
2580                }
2581        } else {
2582                base_port = mlxsw_sp_cluster_base_port_get(local_port);
2583                if (mlxsw_sp->ports[base_port + 1] ||
2584                    mlxsw_sp->ports[base_port + 3]) {
2585                        netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
2586                        return -EINVAL;
2587                }
2588        }
2589
2590        for (i = 0; i < count; i++)
2591                mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
2592
2593        err = mlxsw_sp_port_split_create(mlxsw_sp, base_port, module, count);
2594        if (err) {
2595                dev_err(mlxsw_sp->bus_info->dev, "Failed to create split ports\n");
2596                goto err_port_split_create;
2597        }
2598
2599        return 0;
2600
2601err_port_split_create:
2602        mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
2603        return err;
2604}
2605
2606static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port)
2607{
2608        struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2609        struct mlxsw_sp_port *mlxsw_sp_port;
2610        u8 cur_width, base_port;
2611        unsigned int count;
2612        int i;
2613
2614        mlxsw_sp_port = mlxsw_sp->ports[local_port];
2615        if (!mlxsw_sp_port) {
2616                dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
2617                        local_port);
2618                return -EINVAL;
2619        }
2620
2621        if (!mlxsw_sp_port->split) {
2622                netdev_err(mlxsw_sp_port->dev, "Port wasn't split\n");
2623                return -EINVAL;
2624        }
2625
2626        cur_width = mlxsw_sp_port->mapping.width;
2627        count = cur_width == 1 ? 4 : 2;
2628
2629        base_port = mlxsw_sp_cluster_base_port_get(local_port);
2630
2631        /* Determine which ports to remove. */
2632        if (count == 2 && local_port >= base_port + 2)
2633                base_port = base_port + 2;
2634
2635        for (i = 0; i < count; i++)
2636                mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
2637
2638        mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
2639
2640        return 0;
2641}
2642
2643static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
2644                                     char *pude_pl, void *priv)
2645{
2646        struct mlxsw_sp *mlxsw_sp = priv;
2647        struct mlxsw_sp_port *mlxsw_sp_port;
2648        enum mlxsw_reg_pude_oper_status status;
2649        u8 local_port;
2650
2651        local_port = mlxsw_reg_pude_local_port_get(pude_pl);
2652        mlxsw_sp_port = mlxsw_sp->ports[local_port];
2653        if (!mlxsw_sp_port)
2654                return;
2655
2656        status = mlxsw_reg_pude_oper_status_get(pude_pl);
2657        if (status == MLXSW_PORT_OPER_STATUS_UP) {
2658                netdev_info(mlxsw_sp_port->dev, "link up\n");
2659                netif_carrier_on(mlxsw_sp_port->dev);
2660        } else {
2661                netdev_info(mlxsw_sp_port->dev, "link down\n");
2662                netif_carrier_off(mlxsw_sp_port->dev);
2663        }
2664}
2665
2666static struct mlxsw_event_listener mlxsw_sp_pude_event = {
2667        .func = mlxsw_sp_pude_event_func,
2668        .trap_id = MLXSW_TRAP_ID_PUDE,
2669};
2670
2671static int mlxsw_sp_event_register(struct mlxsw_sp *mlxsw_sp,
2672                                   enum mlxsw_event_trap_id trap_id)
2673{
2674        struct mlxsw_event_listener *el;
2675        char hpkt_pl[MLXSW_REG_HPKT_LEN];
2676        int err;
2677
2678        switch (trap_id) {
2679        case MLXSW_TRAP_ID_PUDE:
2680                el = &mlxsw_sp_pude_event;
2681                break;
2682        }
2683        err = mlxsw_core_event_listener_register(mlxsw_sp->core, el, mlxsw_sp);
2684        if (err)
2685                return err;
2686
2687        mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, trap_id);
2688        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
2689        if (err)
2690                goto err_event_trap_set;
2691
2692        return 0;
2693
2694err_event_trap_set:
2695        mlxsw_core_event_listener_unregister(mlxsw_sp->core, el, mlxsw_sp);
2696        return err;
2697}
2698
2699static void mlxsw_sp_event_unregister(struct mlxsw_sp *mlxsw_sp,
2700                                      enum mlxsw_event_trap_id trap_id)
2701{
2702        struct mlxsw_event_listener *el;
2703
2704        switch (trap_id) {
2705        case MLXSW_TRAP_ID_PUDE:
2706                el = &mlxsw_sp_pude_event;
2707                break;
2708        }
2709        mlxsw_core_event_listener_unregister(mlxsw_sp->core, el, mlxsw_sp);
2710}
2711
2712static void mlxsw_sp_rx_listener_func(struct sk_buff *skb, u8 local_port,
2713                                      void *priv)
2714{
2715        struct mlxsw_sp *mlxsw_sp = priv;
2716        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
2717        struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
2718
2719        if (unlikely(!mlxsw_sp_port)) {
2720                dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n",
2721                                     local_port);
2722                return;
2723        }
2724
2725        skb->dev = mlxsw_sp_port->dev;
2726
2727        pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
2728        u64_stats_update_begin(&pcpu_stats->syncp);
2729        pcpu_stats->rx_packets++;
2730        pcpu_stats->rx_bytes += skb->len;
2731        u64_stats_update_end(&pcpu_stats->syncp);
2732
2733        skb->protocol = eth_type_trans(skb, skb->dev);
2734        netif_receive_skb(skb);
2735}
2736
2737static void mlxsw_sp_rx_listener_mark_func(struct sk_buff *skb, u8 local_port,
2738                                           void *priv)
2739{
2740        skb->offload_fwd_mark = 1;
2741        return mlxsw_sp_rx_listener_func(skb, local_port, priv);
2742}
2743
2744#define MLXSW_SP_RXL(_func, _trap_id, _action)                  \
2745        {                                                       \
2746                .func = _func,                                  \
2747                .local_port = MLXSW_PORT_DONT_CARE,             \
2748                .trap_id = MLXSW_TRAP_ID_##_trap_id,            \
2749                .action = MLXSW_REG_HPKT_ACTION_##_action,      \
2750        }
2751
2752static const struct mlxsw_rx_listener mlxsw_sp_rx_listener[] = {
2753        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, FDB_MC, TRAP_TO_CPU),
2754        /* Traps for specific L2 packet types, not trapped as FDB MC */
2755        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, STP, TRAP_TO_CPU),
2756        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, LACP, TRAP_TO_CPU),
2757        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, EAPOL, TRAP_TO_CPU),
2758        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, LLDP, TRAP_TO_CPU),
2759        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, MMRP, TRAP_TO_CPU),
2760        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, MVRP, TRAP_TO_CPU),
2761        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, RPVST, TRAP_TO_CPU),
2762        MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, DHCP, MIRROR_TO_CPU),
2763        MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, IGMP_QUERY, MIRROR_TO_CPU),
2764        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IGMP_V1_REPORT, TRAP_TO_CPU),
2765        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IGMP_V2_REPORT, TRAP_TO_CPU),
2766        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IGMP_V2_LEAVE, TRAP_TO_CPU),
2767        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IGMP_V3_REPORT, TRAP_TO_CPU),
2768        MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, ARPBC, MIRROR_TO_CPU),
2769        MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, ARPUC, MIRROR_TO_CPU),
2770        /* L3 traps */
2771        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, MTUERROR, TRAP_TO_CPU),
2772        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, TTLERROR, TRAP_TO_CPU),
2773        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, LBERROR, TRAP_TO_CPU),
2774        MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, OSPF, TRAP_TO_CPU),
2775        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IP2ME, TRAP_TO_CPU),
2776        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, RTR_INGRESS0, TRAP_TO_CPU),
2777        MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, HOST_MISS_IPV4, TRAP_TO_CPU),
2778};
2779
2780static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
2781{
2782        char htgt_pl[MLXSW_REG_HTGT_LEN];
2783        char hpkt_pl[MLXSW_REG_HPKT_LEN];
2784        int i;
2785        int err;
2786
2787        mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_RX);
2788        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl);
2789        if (err)
2790                return err;
2791
2792        mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_CTRL);
2793        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl);
2794        if (err)
2795                return err;
2796
2797        for (i = 0; i < ARRAY_SIZE(mlxsw_sp_rx_listener); i++) {
2798                err = mlxsw_core_rx_listener_register(mlxsw_sp->core,
2799                                                      &mlxsw_sp_rx_listener[i],
2800                                                      mlxsw_sp);
2801                if (err)
2802                        goto err_rx_listener_register;
2803
2804                mlxsw_reg_hpkt_pack(hpkt_pl, mlxsw_sp_rx_listener[i].action,
2805                                    mlxsw_sp_rx_listener[i].trap_id);
2806                err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
2807                if (err)
2808                        goto err_rx_trap_set;
2809        }
2810        return 0;
2811
2812err_rx_trap_set:
2813        mlxsw_core_rx_listener_unregister(mlxsw_sp->core,
2814                                          &mlxsw_sp_rx_listener[i],
2815                                          mlxsw_sp);
2816err_rx_listener_register:
2817        for (i--; i >= 0; i--) {
2818                mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD,
2819                                    mlxsw_sp_rx_listener[i].trap_id);
2820                mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
2821
2822                mlxsw_core_rx_listener_unregister(mlxsw_sp->core,
2823                                                  &mlxsw_sp_rx_listener[i],
2824                                                  mlxsw_sp);
2825        }
2826        return err;
2827}
2828
2829static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
2830{
2831        char hpkt_pl[MLXSW_REG_HPKT_LEN];
2832        int i;
2833
2834        for (i = 0; i < ARRAY_SIZE(mlxsw_sp_rx_listener); i++) {
2835                mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD,
2836                                    mlxsw_sp_rx_listener[i].trap_id);
2837                mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
2838
2839                mlxsw_core_rx_listener_unregister(mlxsw_sp->core,
2840                                                  &mlxsw_sp_rx_listener[i],
2841                                                  mlxsw_sp);
2842        }
2843}
2844
2845static int __mlxsw_sp_flood_init(struct mlxsw_core *mlxsw_core,
2846                                 enum mlxsw_reg_sfgc_type type,
2847                                 enum mlxsw_reg_sfgc_bridge_type bridge_type)
2848{
2849        enum mlxsw_flood_table_type table_type;
2850        enum mlxsw_sp_flood_table flood_table;
2851        char sfgc_pl[MLXSW_REG_SFGC_LEN];
2852
2853        if (bridge_type == MLXSW_REG_SFGC_BRIDGE_TYPE_VFID)
2854                table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID;
2855        else
2856                table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFEST;
2857
2858        if (type == MLXSW_REG_SFGC_TYPE_UNKNOWN_UNICAST)
2859                flood_table = MLXSW_SP_FLOOD_TABLE_UC;
2860        else
2861                flood_table = MLXSW_SP_FLOOD_TABLE_BM;
2862
2863        mlxsw_reg_sfgc_pack(sfgc_pl, type, bridge_type, table_type,
2864                            flood_table);
2865        return mlxsw_reg_write(mlxsw_core, MLXSW_REG(sfgc), sfgc_pl);
2866}
2867
2868static int mlxsw_sp_flood_init(struct mlxsw_sp *mlxsw_sp)
2869{
2870        int type, err;
2871
2872        for (type = 0; type < MLXSW_REG_SFGC_TYPE_MAX; type++) {
2873                if (type == MLXSW_REG_SFGC_TYPE_RESERVED)
2874                        continue;
2875
2876                err = __mlxsw_sp_flood_init(mlxsw_sp->core, type,
2877                                            MLXSW_REG_SFGC_BRIDGE_TYPE_VFID);
2878                if (err)
2879                        return err;
2880
2881                err = __mlxsw_sp_flood_init(mlxsw_sp->core, type,
2882                                            MLXSW_REG_SFGC_BRIDGE_TYPE_1Q_FID);
2883                if (err)
2884                        return err;
2885        }
2886
2887        return 0;
2888}
2889
2890static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
2891{
2892        struct mlxsw_resources *resources;
2893        char slcr_pl[MLXSW_REG_SLCR_LEN];
2894        int err;
2895
2896        mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
2897                                     MLXSW_REG_SLCR_LAG_HASH_DMAC |
2898                                     MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
2899                                     MLXSW_REG_SLCR_LAG_HASH_VLANID |
2900                                     MLXSW_REG_SLCR_LAG_HASH_SIP |
2901                                     MLXSW_REG_SLCR_LAG_HASH_DIP |
2902                                     MLXSW_REG_SLCR_LAG_HASH_SPORT |
2903                                     MLXSW_REG_SLCR_LAG_HASH_DPORT |
2904                                     MLXSW_REG_SLCR_LAG_HASH_IPPROTO);
2905        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcr), slcr_pl);
2906        if (err)
2907                return err;
2908
2909        resources = mlxsw_core_resources_get(mlxsw_sp->core);
2910        if (!(resources->max_lag_valid && resources->max_ports_in_lag_valid))
2911                return -EIO;
2912
2913        mlxsw_sp->lags = kcalloc(resources->max_lag,
2914                                 sizeof(struct mlxsw_sp_upper),
2915                                 GFP_KERNEL);
2916        if (!mlxsw_sp->lags)
2917                return -ENOMEM;
2918
2919        return 0;
2920}
2921
2922static void mlxsw_sp_lag_fini(struct mlxsw_sp *mlxsw_sp)
2923{
2924        kfree(mlxsw_sp->lags);
2925}
2926
2927static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
2928                         const struct mlxsw_bus_info *mlxsw_bus_info)
2929{
2930        struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2931        int err;
2932
2933        mlxsw_sp->core = mlxsw_core;
2934        mlxsw_sp->bus_info = mlxsw_bus_info;
2935        INIT_LIST_HEAD(&mlxsw_sp->fids);
2936        INIT_LIST_HEAD(&mlxsw_sp->vfids.list);
2937        INIT_LIST_HEAD(&mlxsw_sp->br_mids.list);
2938
2939        err = mlxsw_sp_base_mac_get(mlxsw_sp);
2940        if (err) {
2941                dev_err(mlxsw_sp->bus_info->dev, "Failed to get base mac\n");
2942                return err;
2943        }
2944
2945        err = mlxsw_sp_event_register(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
2946        if (err) {
2947                dev_err(mlxsw_sp->bus_info->dev, "Failed to register for PUDE events\n");
2948                return err;
2949        }
2950
2951        err = mlxsw_sp_traps_init(mlxsw_sp);
2952        if (err) {
2953                dev_err(mlxsw_sp->bus_info->dev, "Failed to set traps for RX\n");
2954                goto err_rx_listener_register;
2955        }
2956
2957        err = mlxsw_sp_flood_init(mlxsw_sp);
2958        if (err) {
2959                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize flood tables\n");
2960                goto err_flood_init;
2961        }
2962
2963        err = mlxsw_sp_buffers_init(mlxsw_sp);
2964        if (err) {
2965                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize buffers\n");
2966                goto err_buffers_init;
2967        }
2968
2969        err = mlxsw_sp_lag_init(mlxsw_sp);
2970        if (err) {
2971                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize LAG\n");
2972                goto err_lag_init;
2973        }
2974
2975        err = mlxsw_sp_switchdev_init(mlxsw_sp);
2976        if (err) {
2977                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize switchdev\n");
2978                goto err_switchdev_init;
2979        }
2980
2981        err = mlxsw_sp_router_init(mlxsw_sp);
2982        if (err) {
2983                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n");
2984                goto err_router_init;
2985        }
2986
2987        err = mlxsw_sp_span_init(mlxsw_sp);
2988        if (err) {
2989                dev_err(mlxsw_sp->bus_info->dev, "Failed to init span system\n");
2990                goto err_span_init;
2991        }
2992
2993        err = mlxsw_sp_ports_create(mlxsw_sp);
2994        if (err) {
2995                dev_err(mlxsw_sp->bus_info->dev, "Failed to create ports\n");
2996                goto err_ports_create;
2997        }
2998
2999        return 0;
3000
3001err_ports_create:
3002        mlxsw_sp_span_fini(mlxsw_sp);
3003err_span_init:
3004        mlxsw_sp_router_fini(mlxsw_sp);
3005err_router_init:
3006        mlxsw_sp_switchdev_fini(mlxsw_sp);
3007err_switchdev_init:
3008        mlxsw_sp_lag_fini(mlxsw_sp);
3009err_lag_init:
3010        mlxsw_sp_buffers_fini(mlxsw_sp);
3011err_buffers_init:
3012err_flood_init:
3013        mlxsw_sp_traps_fini(mlxsw_sp);
3014err_rx_listener_register:
3015        mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
3016        return err;
3017}
3018
3019static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
3020{
3021        struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3022
3023        mlxsw_sp_ports_remove(mlxsw_sp);
3024        mlxsw_sp_span_fini(mlxsw_sp);
3025        mlxsw_sp_router_fini(mlxsw_sp);
3026        mlxsw_sp_switchdev_fini(mlxsw_sp);
3027        mlxsw_sp_lag_fini(mlxsw_sp);
3028        mlxsw_sp_buffers_fini(mlxsw_sp);
3029        mlxsw_sp_traps_fini(mlxsw_sp);
3030        mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
3031        WARN_ON(!list_empty(&mlxsw_sp->vfids.list));
3032        WARN_ON(!list_empty(&mlxsw_sp->fids));
3033}
3034
3035static struct mlxsw_config_profile mlxsw_sp_config_profile = {
3036        .used_max_vepa_channels         = 1,
3037        .max_vepa_channels              = 0,
3038        .used_max_mid                   = 1,
3039        .max_mid                        = MLXSW_SP_MID_MAX,
3040        .used_max_pgt                   = 1,
3041        .max_pgt                        = 0,
3042        .used_flood_tables              = 1,
3043        .used_flood_mode                = 1,
3044        .flood_mode                     = 3,
3045        .max_fid_offset_flood_tables    = 2,
3046        .fid_offset_flood_table_size    = VLAN_N_VID - 1,
3047        .max_fid_flood_tables           = 2,
3048        .fid_flood_table_size           = MLXSW_SP_VFID_MAX,
3049        .used_max_ib_mc                 = 1,
3050        .max_ib_mc                      = 0,
3051        .used_max_pkey                  = 1,
3052        .max_pkey                       = 0,
3053        .used_kvd_split_data            = 1,
3054        .kvd_hash_granularity           = MLXSW_SP_KVD_GRANULARITY,
3055        .kvd_hash_single_parts          = 2,
3056        .kvd_hash_double_parts          = 1,
3057        .kvd_linear_size                = MLXSW_SP_KVD_LINEAR_SIZE,
3058        .swid_config                    = {
3059                {
3060                        .used_type      = 1,
3061                        .type           = MLXSW_PORT_SWID_TYPE_ETH,
3062                }
3063        },
3064        .resource_query_enable          = 1,
3065};
3066
3067static struct mlxsw_driver mlxsw_sp_driver = {
3068        .kind                           = MLXSW_DEVICE_KIND_SPECTRUM,
3069        .owner                          = THIS_MODULE,
3070        .priv_size                      = sizeof(struct mlxsw_sp),
3071        .init                           = mlxsw_sp_init,
3072        .fini                           = mlxsw_sp_fini,
3073        .port_split                     = mlxsw_sp_port_split,
3074        .port_unsplit                   = mlxsw_sp_port_unsplit,
3075        .sb_pool_get                    = mlxsw_sp_sb_pool_get,
3076        .sb_pool_set                    = mlxsw_sp_sb_pool_set,
3077        .sb_port_pool_get               = mlxsw_sp_sb_port_pool_get,
3078        .sb_port_pool_set               = mlxsw_sp_sb_port_pool_set,
3079        .sb_tc_pool_bind_get            = mlxsw_sp_sb_tc_pool_bind_get,
3080        .sb_tc_pool_bind_set            = mlxsw_sp_sb_tc_pool_bind_set,
3081        .sb_occ_snapshot                = mlxsw_sp_sb_occ_snapshot,
3082        .sb_occ_max_clear               = mlxsw_sp_sb_occ_max_clear,
3083        .sb_occ_port_pool_get           = mlxsw_sp_sb_occ_port_pool_get,
3084        .sb_occ_tc_port_bind_get        = mlxsw_sp_sb_occ_tc_port_bind_get,
3085        .txhdr_construct                = mlxsw_sp_txhdr_construct,
3086        .txhdr_len                      = MLXSW_TXHDR_LEN,
3087        .profile                        = &mlxsw_sp_config_profile,
3088};
3089
3090static bool mlxsw_sp_port_dev_check(const struct net_device *dev)
3091{
3092        return dev->netdev_ops == &mlxsw_sp_port_netdev_ops;
3093}
3094
3095static struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev)
3096{
3097        struct net_device *lower_dev;
3098        struct list_head *iter;
3099
3100        if (mlxsw_sp_port_dev_check(dev))
3101                return netdev_priv(dev);
3102
3103        netdev_for_each_all_lower_dev(dev, lower_dev, iter) {
3104                if (mlxsw_sp_port_dev_check(lower_dev))
3105                        return netdev_priv(lower_dev);
3106        }
3107        return NULL;
3108}
3109
3110static struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev)
3111{
3112        struct mlxsw_sp_port *mlxsw_sp_port;
3113
3114        mlxsw_sp_port = mlxsw_sp_port_dev_lower_find(dev);
3115        return mlxsw_sp_port ? mlxsw_sp_port->mlxsw_sp : NULL;
3116}
3117
3118static struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev)
3119{
3120        struct net_device *lower_dev;
3121        struct list_head *iter;
3122
3123        if (mlxsw_sp_port_dev_check(dev))
3124                return netdev_priv(dev);
3125
3126        netdev_for_each_all_lower_dev_rcu(dev, lower_dev, iter) {
3127                if (mlxsw_sp_port_dev_check(lower_dev))
3128                        return netdev_priv(lower_dev);
3129        }
3130        return NULL;
3131}
3132
3133struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev)
3134{
3135        struct mlxsw_sp_port *mlxsw_sp_port;
3136
3137        rcu_read_lock();
3138        mlxsw_sp_port = mlxsw_sp_port_dev_lower_find_rcu(dev);
3139        if (mlxsw_sp_port)
3140                dev_hold(mlxsw_sp_port->dev);
3141        rcu_read_unlock();
3142        return mlxsw_sp_port;
3143}
3144
3145void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port)
3146{
3147        dev_put(mlxsw_sp_port->dev);
3148}
3149
3150static bool mlxsw_sp_rif_should_config(struct mlxsw_sp_rif *r,
3151                                       unsigned long event)
3152{
3153        switch (event) {
3154        case NETDEV_UP:
3155                if (!r)
3156                        return true;
3157                r->ref_count++;
3158                return false;
3159        case NETDEV_DOWN:
3160                if (r && --r->ref_count == 0)
3161                        return true;
3162                /* It is possible we already removed the RIF ourselves
3163                 * if it was assigned to a netdev that is now a bridge
3164                 * or LAG slave.
3165                 */
3166                return false;
3167        }
3168
3169        return false;
3170}
3171
3172static int mlxsw_sp_avail_rif_get(struct mlxsw_sp *mlxsw_sp)
3173{
3174        struct mlxsw_resources *resources;
3175        int i;
3176
3177        resources = mlxsw_core_resources_get(mlxsw_sp->core);
3178        for (i = 0; i < resources->max_rif; i++)
3179                if (!mlxsw_sp->rifs[i])
3180                        return i;
3181
3182        return MLXSW_SP_INVALID_RIF;
3183}
3184
3185static void mlxsw_sp_vport_rif_sp_attr_get(struct mlxsw_sp_port *mlxsw_sp_vport,
3186                                           bool *p_lagged, u16 *p_system_port)
3187{
3188        u8 local_port = mlxsw_sp_vport->local_port;
3189
3190        *p_lagged = mlxsw_sp_vport->lagged;
3191        *p_system_port = *p_lagged ? mlxsw_sp_vport->lag_id : local_port;
3192}
3193
3194static int mlxsw_sp_vport_rif_sp_op(struct mlxsw_sp_port *mlxsw_sp_vport,
3195                                    struct net_device *l3_dev, u16 rif,
3196                                    bool create)
3197{
3198        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
3199        bool lagged = mlxsw_sp_vport->lagged;
3200        char ritr_pl[MLXSW_REG_RITR_LEN];
3201        u16 system_port;
3202
3203        mlxsw_reg_ritr_pack(ritr_pl, create, MLXSW_REG_RITR_SP_IF, rif,
3204                            l3_dev->mtu, l3_dev->dev_addr);
3205
3206        mlxsw_sp_vport_rif_sp_attr_get(mlxsw_sp_vport, &lagged, &system_port);
3207        mlxsw_reg_ritr_sp_if_pack(ritr_pl, lagged, system_port,
3208                                  mlxsw_sp_vport_vid_get(mlxsw_sp_vport));
3209
3210        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
3211}
3212
3213static void mlxsw_sp_vport_rif_sp_leave(struct mlxsw_sp_port *mlxsw_sp_vport);
3214
3215static struct mlxsw_sp_fid *
3216mlxsw_sp_rfid_alloc(u16 fid, struct net_device *l3_dev)
3217{
3218        struct mlxsw_sp_fid *f;
3219
3220        f = kzalloc(sizeof(*f), GFP_KERNEL);
3221        if (!f)
3222                return NULL;
3223
3224        f->leave = mlxsw_sp_vport_rif_sp_leave;
3225        f->ref_count = 0;
3226        f->dev = l3_dev;
3227        f->fid = fid;
3228
3229        return f;
3230}
3231
3232static struct mlxsw_sp_rif *
3233mlxsw_sp_rif_alloc(u16 rif, struct net_device *l3_dev, struct mlxsw_sp_fid *f)
3234{
3235        struct mlxsw_sp_rif *r;
3236
3237        r = kzalloc(sizeof(*r), GFP_KERNEL);
3238        if (!r)
3239                return NULL;
3240
3241        ether_addr_copy(r->addr, l3_dev->dev_addr);
3242        r->mtu = l3_dev->mtu;
3243        r->ref_count = 1;
3244        r->dev = l3_dev;
3245        r->rif = rif;
3246        r->f = f;
3247
3248        return r;
3249}
3250
3251static struct mlxsw_sp_rif *
3252mlxsw_sp_vport_rif_sp_create(struct mlxsw_sp_port *mlxsw_sp_vport,
3253                             struct net_device *l3_dev)
3254{
3255        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
3256        struct mlxsw_sp_fid *f;
3257        struct mlxsw_sp_rif *r;
3258        u16 fid, rif;
3259        int err;
3260
3261        rif = mlxsw_sp_avail_rif_get(mlxsw_sp);
3262        if (rif == MLXSW_SP_INVALID_RIF)
3263                return ERR_PTR(-ERANGE);
3264
3265        err = mlxsw_sp_vport_rif_sp_op(mlxsw_sp_vport, l3_dev, rif, true);
3266        if (err)
3267                return ERR_PTR(err);
3268
3269        fid = mlxsw_sp_rif_sp_to_fid(rif);
3270        err = mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, fid, true);
3271        if (err)
3272                goto err_rif_fdb_op;
3273
3274        f = mlxsw_sp_rfid_alloc(fid, l3_dev);
3275        if (!f) {
3276                err = -ENOMEM;
3277                goto err_rfid_alloc;
3278        }
3279
3280        r = mlxsw_sp_rif_alloc(rif, l3_dev, f);
3281        if (!r) {
3282                err = -ENOMEM;
3283                goto err_rif_alloc;
3284        }
3285
3286        f->r = r;
3287        mlxsw_sp->rifs[rif] = r;
3288
3289        return r;
3290
3291err_rif_alloc:
3292        kfree(f);
3293err_rfid_alloc:
3294        mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, fid, false);
3295err_rif_fdb_op:
3296        mlxsw_sp_vport_rif_sp_op(mlxsw_sp_vport, l3_dev, rif, false);
3297        return ERR_PTR(err);
3298}
3299
3300static void mlxsw_sp_vport_rif_sp_destroy(struct mlxsw_sp_port *mlxsw_sp_vport,
3301                                          struct mlxsw_sp_rif *r)
3302{
3303        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
3304        struct net_device *l3_dev = r->dev;
3305        struct mlxsw_sp_fid *f = r->f;
3306        u16 fid = f->fid;
3307        u16 rif = r->rif;
3308
3309        mlxsw_sp->rifs[rif] = NULL;
3310        f->r = NULL;
3311
3312        kfree(r);
3313
3314        kfree(f);
3315
3316        mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, fid, false);
3317
3318        mlxsw_sp_vport_rif_sp_op(mlxsw_sp_vport, l3_dev, rif, false);
3319}
3320
3321static int mlxsw_sp_vport_rif_sp_join(struct mlxsw_sp_port *mlxsw_sp_vport,
3322                                      struct net_device *l3_dev)
3323{
3324        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
3325        struct mlxsw_sp_rif *r;
3326
3327        r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
3328        if (!r) {
3329                r = mlxsw_sp_vport_rif_sp_create(mlxsw_sp_vport, l3_dev);
3330                if (IS_ERR(r))
3331                        return PTR_ERR(r);
3332        }
3333
3334        mlxsw_sp_vport_fid_set(mlxsw_sp_vport, r->f);
3335        r->f->ref_count++;
3336
3337        netdev_dbg(mlxsw_sp_vport->dev, "Joined FID=%d\n", r->f->fid);
3338
3339        return 0;
3340}
3341
3342static void mlxsw_sp_vport_rif_sp_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
3343{
3344        struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
3345
3346        netdev_dbg(mlxsw_sp_vport->dev, "Left FID=%d\n", f->fid);
3347
3348        mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
3349        if (--f->ref_count == 0)
3350                mlxsw_sp_vport_rif_sp_destroy(mlxsw_sp_vport, f->r);
3351}
3352
3353static int mlxsw_sp_inetaddr_vport_event(struct net_device *l3_dev,
3354                                         struct net_device *port_dev,
3355                                         unsigned long event, u16 vid)
3356{
3357        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(port_dev);
3358        struct mlxsw_sp_port *mlxsw_sp_vport;
3359
3360        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
3361        if (WARN_ON(!mlxsw_sp_vport))
3362                return -EINVAL;
3363
3364        switch (event) {
3365        case NETDEV_UP:
3366                return mlxsw_sp_vport_rif_sp_join(mlxsw_sp_vport, l3_dev);
3367        case NETDEV_DOWN:
3368                mlxsw_sp_vport_rif_sp_leave(mlxsw_sp_vport);
3369                break;
3370        }
3371
3372        return 0;
3373}
3374
3375static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev,
3376                                        unsigned long event)
3377{
3378        if (netif_is_bridge_port(port_dev) || netif_is_lag_port(port_dev))
3379                return 0;
3380
3381        return mlxsw_sp_inetaddr_vport_event(port_dev, port_dev, event, 1);
3382}
3383
3384static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev,
3385                                         struct net_device *lag_dev,
3386                                         unsigned long event, u16 vid)
3387{
3388        struct net_device *port_dev;
3389        struct list_head *iter;
3390        int err;
3391
3392        netdev_for_each_lower_dev(lag_dev, port_dev, iter) {
3393                if (mlxsw_sp_port_dev_check(port_dev)) {
3394                        err = mlxsw_sp_inetaddr_vport_event(l3_dev, port_dev,
3395                                                            event, vid);
3396                        if (err)
3397                                return err;
3398                }
3399        }
3400
3401        return 0;
3402}
3403
3404static int mlxsw_sp_inetaddr_lag_event(struct net_device *lag_dev,
3405                                       unsigned long event)
3406{
3407        if (netif_is_bridge_port(lag_dev))
3408                return 0;
3409
3410        return __mlxsw_sp_inetaddr_lag_event(lag_dev, lag_dev, event, 1);
3411}
3412
3413static struct mlxsw_sp_fid *mlxsw_sp_bridge_fid_get(struct mlxsw_sp *mlxsw_sp,
3414                                                    struct net_device *l3_dev)
3415{
3416        u16 fid;
3417
3418        if (is_vlan_dev(l3_dev))
3419                fid = vlan_dev_vlan_id(l3_dev);
3420        else if (mlxsw_sp->master_bridge.dev == l3_dev)
3421                fid = 1;
3422        else
3423                return mlxsw_sp_vfid_find(mlxsw_sp, l3_dev);
3424
3425        return mlxsw_sp_fid_find(mlxsw_sp, fid);
3426}
3427
3428static enum mlxsw_flood_table_type mlxsw_sp_flood_table_type_get(u16 fid)
3429{
3430        return mlxsw_sp_fid_is_vfid(fid) ? MLXSW_REG_SFGC_TABLE_TYPE_FID :
3431               MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFEST;
3432}
3433
3434static u16 mlxsw_sp_flood_table_index_get(u16 fid)
3435{
3436        return mlxsw_sp_fid_is_vfid(fid) ? mlxsw_sp_fid_to_vfid(fid) : fid;
3437}
3438
3439static int mlxsw_sp_router_port_flood_set(struct mlxsw_sp *mlxsw_sp, u16 fid,
3440                                          bool set)
3441{
3442        enum mlxsw_flood_table_type table_type;
3443        char *sftr_pl;
3444        u16 index;
3445        int err;
3446
3447        sftr_pl = kmalloc(MLXSW_REG_SFTR_LEN, GFP_KERNEL);
3448        if (!sftr_pl)
3449                return -ENOMEM;
3450
3451        table_type = mlxsw_sp_flood_table_type_get(fid);
3452        index = mlxsw_sp_flood_table_index_get(fid);
3453        mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_BM, index, table_type,
3454                            1, MLXSW_PORT_ROUTER_PORT, set);
3455        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl);
3456
3457        kfree(sftr_pl);
3458        return err;
3459}
3460
3461static enum mlxsw_reg_ritr_if_type mlxsw_sp_rif_type_get(u16 fid)
3462{
3463        if (mlxsw_sp_fid_is_vfid(fid))
3464                return MLXSW_REG_RITR_FID_IF;
3465        else
3466                return MLXSW_REG_RITR_VLAN_IF;
3467}
3468
3469static int mlxsw_sp_rif_bridge_op(struct mlxsw_sp *mlxsw_sp,
3470                                  struct net_device *l3_dev,
3471                                  u16 fid, u16 rif,
3472                                  bool create)
3473{
3474        enum mlxsw_reg_ritr_if_type rif_type;
3475        char ritr_pl[MLXSW_REG_RITR_LEN];
3476
3477        rif_type = mlxsw_sp_rif_type_get(fid);
3478        mlxsw_reg_ritr_pack(ritr_pl, create, rif_type, rif, l3_dev->mtu,
3479                            l3_dev->dev_addr);
3480        mlxsw_reg_ritr_fid_set(ritr_pl, rif_type, fid);
3481
3482        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
3483}
3484
3485static int mlxsw_sp_rif_bridge_create(struct mlxsw_sp *mlxsw_sp,
3486                                      struct net_device *l3_dev,
3487                                      struct mlxsw_sp_fid *f)
3488{
3489        struct mlxsw_sp_rif *r;
3490        u16 rif;
3491        int err;
3492
3493        rif = mlxsw_sp_avail_rif_get(mlxsw_sp);
3494        if (rif == MLXSW_SP_INVALID_RIF)
3495                return -ERANGE;
3496
3497        err = mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, true);
3498        if (err)
3499                return err;
3500
3501        err = mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, true);
3502        if (err)
3503                goto err_rif_bridge_op;
3504
3505        err = mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, true);
3506        if (err)
3507                goto err_rif_fdb_op;
3508
3509        r = mlxsw_sp_rif_alloc(rif, l3_dev, f);
3510        if (!r) {
3511                err = -ENOMEM;
3512                goto err_rif_alloc;
3513        }
3514
3515        f->r = r;
3516        mlxsw_sp->rifs[rif] = r;
3517
3518        netdev_dbg(l3_dev, "RIF=%d created\n", rif);
3519
3520        return 0;
3521
3522err_rif_alloc:
3523        mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, false);
3524err_rif_fdb_op:
3525        mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false);
3526err_rif_bridge_op:
3527        mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, false);
3528        return err;
3529}
3530
3531void mlxsw_sp_rif_bridge_destroy(struct mlxsw_sp *mlxsw_sp,
3532                                 struct mlxsw_sp_rif *r)
3533{
3534        struct net_device *l3_dev = r->dev;
3535        struct mlxsw_sp_fid *f = r->f;
3536        u16 rif = r->rif;
3537
3538        mlxsw_sp->rifs[rif] = NULL;
3539        f->r = NULL;
3540
3541        kfree(r);
3542
3543        mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, false);
3544
3545        mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false);
3546
3547        mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, false);
3548
3549        netdev_dbg(l3_dev, "RIF=%d destroyed\n", rif);
3550}
3551
3552static int mlxsw_sp_inetaddr_bridge_event(struct net_device *l3_dev,
3553                                          struct net_device *br_dev,
3554                                          unsigned long event)
3555{
3556        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(l3_dev);
3557        struct mlxsw_sp_fid *f;
3558
3559        /* FID can either be an actual FID if the L3 device is the
3560         * VLAN-aware bridge or a VLAN device on top. Otherwise, the
3561         * L3 device is a VLAN-unaware bridge and we get a vFID.
3562         */
3563        f = mlxsw_sp_bridge_fid_get(mlxsw_sp, l3_dev);
3564        if (WARN_ON(!f))
3565                return -EINVAL;
3566
3567        switch (event) {
3568        case NETDEV_UP:
3569                return mlxsw_sp_rif_bridge_create(mlxsw_sp, l3_dev, f);
3570        case NETDEV_DOWN:
3571                mlxsw_sp_rif_bridge_destroy(mlxsw_sp, f->r);
3572                break;
3573        }
3574
3575        return 0;
3576}
3577
3578static int mlxsw_sp_inetaddr_vlan_event(struct net_device *vlan_dev,
3579                                        unsigned long event)
3580{
3581        struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
3582        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(vlan_dev);
3583        u16 vid = vlan_dev_vlan_id(vlan_dev);
3584
3585        if (mlxsw_sp_port_dev_check(real_dev))
3586                return mlxsw_sp_inetaddr_vport_event(vlan_dev, real_dev, event,
3587                                                     vid);
3588        else if (netif_is_lag_master(real_dev))
3589                return __mlxsw_sp_inetaddr_lag_event(vlan_dev, real_dev, event,
3590                                                     vid);
3591        else if (netif_is_bridge_master(real_dev) &&
3592                 mlxsw_sp->master_bridge.dev == real_dev)
3593                return mlxsw_sp_inetaddr_bridge_event(vlan_dev, real_dev,
3594                                                      event);
3595
3596        return 0;
3597}
3598
3599static int mlxsw_sp_inetaddr_event(struct notifier_block *unused,
3600                                   unsigned long event, void *ptr)
3601{
3602        struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
3603        struct net_device *dev = ifa->ifa_dev->dev;
3604        struct mlxsw_sp *mlxsw_sp;
3605        struct mlxsw_sp_rif *r;
3606        int err = 0;
3607
3608        mlxsw_sp = mlxsw_sp_lower_get(dev);
3609        if (!mlxsw_sp)
3610                goto out;
3611
3612        r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
3613        if (!mlxsw_sp_rif_should_config(r, event))
3614                goto out;
3615
3616        if (mlxsw_sp_port_dev_check(dev))
3617                err = mlxsw_sp_inetaddr_port_event(dev, event);
3618        else if (netif_is_lag_master(dev))
3619                err = mlxsw_sp_inetaddr_lag_event(dev, event);
3620        else if (netif_is_bridge_master(dev))
3621                err = mlxsw_sp_inetaddr_bridge_event(dev, dev, event);
3622        else if (is_vlan_dev(dev))
3623                err = mlxsw_sp_inetaddr_vlan_event(dev, event);
3624
3625out:
3626        return notifier_from_errno(err);
3627}
3628
3629static int mlxsw_sp_rif_edit(struct mlxsw_sp *mlxsw_sp, u16 rif,
3630                             const char *mac, int mtu)
3631{
3632        char ritr_pl[MLXSW_REG_RITR_LEN];
3633        int err;
3634
3635        mlxsw_reg_ritr_rif_pack(ritr_pl, rif);
3636        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
3637        if (err)
3638                return err;
3639
3640        mlxsw_reg_ritr_mtu_set(ritr_pl, mtu);
3641        mlxsw_reg_ritr_if_mac_memcpy_to(ritr_pl, mac);
3642        mlxsw_reg_ritr_op_set(ritr_pl, MLXSW_REG_RITR_RIF_CREATE);
3643        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
3644}
3645
3646static int mlxsw_sp_netdevice_router_port_event(struct net_device *dev)
3647{
3648        struct mlxsw_sp *mlxsw_sp;
3649        struct mlxsw_sp_rif *r;
3650        int err;
3651
3652        mlxsw_sp = mlxsw_sp_lower_get(dev);
3653        if (!mlxsw_sp)
3654                return 0;
3655
3656        r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
3657        if (!r)
3658                return 0;
3659
3660        err = mlxsw_sp_rif_fdb_op(mlxsw_sp, r->addr, r->f->fid, false);
3661        if (err)
3662                return err;
3663
3664        err = mlxsw_sp_rif_edit(mlxsw_sp, r->rif, dev->dev_addr, dev->mtu);
3665        if (err)
3666                goto err_rif_edit;
3667
3668        err = mlxsw_sp_rif_fdb_op(mlxsw_sp, dev->dev_addr, r->f->fid, true);
3669        if (err)
3670                goto err_rif_fdb_op;
3671
3672        ether_addr_copy(r->addr, dev->dev_addr);
3673        r->mtu = dev->mtu;
3674
3675        netdev_dbg(dev, "Updated RIF=%d\n", r->rif);
3676
3677        return 0;
3678
3679err_rif_fdb_op:
3680        mlxsw_sp_rif_edit(mlxsw_sp, r->rif, r->addr, r->mtu);
3681err_rif_edit:
3682        mlxsw_sp_rif_fdb_op(mlxsw_sp, r->addr, r->f->fid, true);
3683        return err;
3684}
3685
3686static bool mlxsw_sp_lag_port_fid_member(struct mlxsw_sp_port *lag_port,
3687                                         u16 fid)
3688{
3689        if (mlxsw_sp_fid_is_vfid(fid))
3690                return mlxsw_sp_port_vport_find_by_fid(lag_port, fid);
3691        else
3692                return test_bit(fid, lag_port->active_vlans);
3693}
3694
3695static bool mlxsw_sp_port_fdb_should_flush(struct mlxsw_sp_port *mlxsw_sp_port,
3696                                           u16 fid)
3697{
3698        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3699        u8 local_port = mlxsw_sp_port->local_port;
3700        u16 lag_id = mlxsw_sp_port->lag_id;
3701        struct mlxsw_resources *resources;
3702        int i, count = 0;
3703
3704        if (!mlxsw_sp_port->lagged)
3705                return true;
3706
3707        resources = mlxsw_core_resources_get(mlxsw_sp->core);
3708        for (i = 0; i < resources->max_ports_in_lag; i++) {
3709                struct mlxsw_sp_port *lag_port;
3710
3711                lag_port = mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i);
3712                if (!lag_port || lag_port->local_port == local_port)
3713                        continue;
3714                if (mlxsw_sp_lag_port_fid_member(lag_port, fid))
3715                        count++;
3716        }
3717
3718        return !count;
3719}
3720
3721static int
3722mlxsw_sp_port_fdb_flush_by_port_fid(const struct mlxsw_sp_port *mlxsw_sp_port,
3723                                    u16 fid)
3724{
3725        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3726        char sfdf_pl[MLXSW_REG_SFDF_LEN];
3727
3728        mlxsw_reg_sfdf_pack(sfdf_pl, MLXSW_REG_SFDF_FLUSH_PER_PORT_AND_FID);
3729        mlxsw_reg_sfdf_fid_set(sfdf_pl, fid);
3730        mlxsw_reg_sfdf_port_fid_system_port_set(sfdf_pl,
3731                                                mlxsw_sp_port->local_port);
3732
3733        netdev_dbg(mlxsw_sp_port->dev, "FDB flushed using Port=%d, FID=%d\n",
3734                   mlxsw_sp_port->local_port, fid);
3735
3736        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdf), sfdf_pl);
3737}
3738
3739static int
3740mlxsw_sp_port_fdb_flush_by_lag_id_fid(const struct mlxsw_sp_port *mlxsw_sp_port,
3741                                      u16 fid)
3742{
3743        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3744        char sfdf_pl[MLXSW_REG_SFDF_LEN];
3745
3746        mlxsw_reg_sfdf_pack(sfdf_pl, MLXSW_REG_SFDF_FLUSH_PER_LAG_AND_FID);
3747        mlxsw_reg_sfdf_fid_set(sfdf_pl, fid);
3748        mlxsw_reg_sfdf_lag_fid_lag_id_set(sfdf_pl, mlxsw_sp_port->lag_id);
3749
3750        netdev_dbg(mlxsw_sp_port->dev, "FDB flushed using LAG ID=%d, FID=%d\n",
3751                   mlxsw_sp_port->lag_id, fid);
3752
3753        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdf), sfdf_pl);
3754}
3755
3756int mlxsw_sp_port_fdb_flush(struct mlxsw_sp_port *mlxsw_sp_port, u16 fid)
3757{
3758        if (!mlxsw_sp_port_fdb_should_flush(mlxsw_sp_port, fid))
3759                return 0;
3760
3761        if (mlxsw_sp_port->lagged)
3762                return mlxsw_sp_port_fdb_flush_by_lag_id_fid(mlxsw_sp_port,
3763                                                             fid);
3764        else
3765                return mlxsw_sp_port_fdb_flush_by_port_fid(mlxsw_sp_port, fid);
3766}
3767
3768static void mlxsw_sp_master_bridge_gone_sync(struct mlxsw_sp *mlxsw_sp)
3769{
3770        struct mlxsw_sp_fid *f, *tmp;
3771
3772        list_for_each_entry_safe(f, tmp, &mlxsw_sp->fids, list)
3773                if (--f->ref_count == 0)
3774                        mlxsw_sp_fid_destroy(mlxsw_sp, f);
3775                else
3776                        WARN_ON_ONCE(1);
3777}
3778
3779static bool mlxsw_sp_master_bridge_check(struct mlxsw_sp *mlxsw_sp,
3780                                         struct net_device *br_dev)
3781{
3782        return !mlxsw_sp->master_bridge.dev ||
3783               mlxsw_sp->master_bridge.dev == br_dev;
3784}
3785
3786static void mlxsw_sp_master_bridge_inc(struct mlxsw_sp *mlxsw_sp,
3787                                       struct net_device *br_dev)
3788{
3789        mlxsw_sp->master_bridge.dev = br_dev;
3790        mlxsw_sp->master_bridge.ref_count++;
3791}
3792
3793static void mlxsw_sp_master_bridge_dec(struct mlxsw_sp *mlxsw_sp)
3794{
3795        if (--mlxsw_sp->master_bridge.ref_count == 0) {
3796                mlxsw_sp->master_bridge.dev = NULL;
3797                /* It's possible upper VLAN devices are still holding
3798                 * references to underlying FIDs. Drop the reference
3799                 * and release the resources if it was the last one.
3800                 * If it wasn't, then something bad happened.
3801                 */
3802                mlxsw_sp_master_bridge_gone_sync(mlxsw_sp);
3803        }
3804}
3805
3806static int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port,
3807                                     struct net_device *br_dev)
3808{
3809        struct net_device *dev = mlxsw_sp_port->dev;
3810        int err;
3811
3812        /* When port is not bridged untagged packets are tagged with
3813         * PVID=VID=1, thereby creating an implicit VLAN interface in
3814         * the device. Remove it and let bridge code take care of its
3815         * own VLANs.
3816         */
3817        err = mlxsw_sp_port_kill_vid(dev, 0, 1);
3818        if (err)
3819                return err;
3820
3821        mlxsw_sp_master_bridge_inc(mlxsw_sp_port->mlxsw_sp, br_dev);
3822
3823        mlxsw_sp_port->learning = 1;
3824        mlxsw_sp_port->learning_sync = 1;
3825        mlxsw_sp_port->uc_flood = 1;
3826        mlxsw_sp_port->bridged = 1;
3827
3828        return 0;
3829}
3830
3831static void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port)
3832{
3833        struct net_device *dev = mlxsw_sp_port->dev;
3834
3835        mlxsw_sp_port_pvid_set(mlxsw_sp_port, 1);
3836
3837        mlxsw_sp_master_bridge_dec(mlxsw_sp_port->mlxsw_sp);
3838
3839        mlxsw_sp_port->learning = 0;
3840        mlxsw_sp_port->learning_sync = 0;
3841        mlxsw_sp_port->uc_flood = 0;
3842        mlxsw_sp_port->bridged = 0;
3843
3844        /* Add implicit VLAN interface in the device, so that untagged
3845         * packets will be classified to the default vFID.
3846         */
3847        mlxsw_sp_port_add_vid(dev, 0, 1);
3848}
3849
3850static int mlxsw_sp_lag_create(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
3851{
3852        char sldr_pl[MLXSW_REG_SLDR_LEN];
3853
3854        mlxsw_reg_sldr_lag_create_pack(sldr_pl, lag_id);
3855        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
3856}
3857
3858static int mlxsw_sp_lag_destroy(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
3859{
3860        char sldr_pl[MLXSW_REG_SLDR_LEN];
3861
3862        mlxsw_reg_sldr_lag_destroy_pack(sldr_pl, lag_id);
3863        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
3864}
3865
3866static int mlxsw_sp_lag_col_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
3867                                     u16 lag_id, u8 port_index)
3868{
3869        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3870        char slcor_pl[MLXSW_REG_SLCOR_LEN];
3871
3872        mlxsw_reg_slcor_port_add_pack(slcor_pl, mlxsw_sp_port->local_port,
3873                                      lag_id, port_index);
3874        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
3875}
3876
3877static int mlxsw_sp_lag_col_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
3878                                        u16 lag_id)
3879{
3880        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3881        char slcor_pl[MLXSW_REG_SLCOR_LEN];
3882
3883        mlxsw_reg_slcor_port_remove_pack(slcor_pl, mlxsw_sp_port->local_port,
3884                                         lag_id);
3885        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
3886}
3887
3888static int mlxsw_sp_lag_col_port_enable(struct mlxsw_sp_port *mlxsw_sp_port,
3889                                        u16 lag_id)
3890{
3891        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3892        char slcor_pl[MLXSW_REG_SLCOR_LEN];
3893
3894        mlxsw_reg_slcor_col_enable_pack(slcor_pl, mlxsw_sp_port->local_port,
3895                                        lag_id);
3896        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
3897}
3898
3899static int mlxsw_sp_lag_col_port_disable(struct mlxsw_sp_port *mlxsw_sp_port,
3900                                         u16 lag_id)
3901{
3902        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3903        char slcor_pl[MLXSW_REG_SLCOR_LEN];
3904
3905        mlxsw_reg_slcor_col_disable_pack(slcor_pl, mlxsw_sp_port->local_port,
3906                                         lag_id);
3907        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
3908}
3909
3910static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
3911                                  struct net_device *lag_dev,
3912                                  u16 *p_lag_id)
3913{
3914        struct mlxsw_resources *resources;
3915        struct mlxsw_sp_upper *lag;
3916        int free_lag_id = -1;
3917        int i;
3918
3919        resources = mlxsw_core_resources_get(mlxsw_sp->core);
3920        for (i = 0; i < resources->max_lag; i++) {
3921                lag = mlxsw_sp_lag_get(mlxsw_sp, i);
3922                if (lag->ref_count) {
3923                        if (lag->dev == lag_dev) {
3924                                *p_lag_id = i;
3925                                return 0;
3926                        }
3927                } else if (free_lag_id < 0) {
3928                        free_lag_id = i;
3929                }
3930        }
3931        if (free_lag_id < 0)
3932                return -EBUSY;
3933        *p_lag_id = free_lag_id;
3934        return 0;
3935}
3936
3937static bool
3938mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
3939                          struct net_device *lag_dev,
3940                          struct netdev_lag_upper_info *lag_upper_info)
3941{
3942        u16 lag_id;
3943
3944        if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0)
3945                return false;
3946        if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
3947                return false;
3948        return true;
3949}
3950
3951static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp *mlxsw_sp,
3952                                       u16 lag_id, u8 *p_port_index)
3953{
3954        struct mlxsw_resources *resources;
3955        int i;
3956
3957        resources = mlxsw_core_resources_get(mlxsw_sp->core);
3958        for (i = 0; i < resources->max_ports_in_lag; i++) {
3959                if (!mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i)) {
3960                        *p_port_index = i;
3961                        return 0;
3962                }
3963        }
3964        return -EBUSY;
3965}
3966
3967static void
3968mlxsw_sp_port_pvid_vport_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
3969                                  u16 lag_id)
3970{
3971        struct mlxsw_sp_port *mlxsw_sp_vport;
3972        struct mlxsw_sp_fid *f;
3973
3974        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, 1);
3975        if (WARN_ON(!mlxsw_sp_vport))
3976                return;
3977
3978        /* If vPort is assigned a RIF, then leave it since it's no
3979         * longer valid.
3980         */
3981        f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
3982        if (f)
3983                f->leave(mlxsw_sp_vport);
3984
3985        mlxsw_sp_vport->lag_id = lag_id;
3986        mlxsw_sp_vport->lagged = 1;
3987}
3988
3989static void
3990mlxsw_sp_port_pvid_vport_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port)
3991{
3992        struct mlxsw_sp_port *mlxsw_sp_vport;
3993        struct mlxsw_sp_fid *f;
3994
3995        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, 1);
3996        if (WARN_ON(!mlxsw_sp_vport))
3997                return;
3998
3999        f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
4000        if (f)
4001                f->leave(mlxsw_sp_vport);
4002
4003        mlxsw_sp_vport->lagged = 0;
4004}
4005
4006static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
4007                                  struct net_device *lag_dev)
4008{
4009        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4010        struct mlxsw_sp_upper *lag;
4011        u16 lag_id;
4012        u8 port_index;
4013        int err;
4014
4015        err = mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id);
4016        if (err)
4017                return err;
4018        lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
4019        if (!lag->ref_count) {
4020                err = mlxsw_sp_lag_create(mlxsw_sp, lag_id);
4021                if (err)
4022                        return err;
4023                lag->dev = lag_dev;
4024        }
4025
4026        err = mlxsw_sp_port_lag_index_get(mlxsw_sp, lag_id, &port_index);
4027        if (err)
4028                return err;
4029        err = mlxsw_sp_lag_col_port_add(mlxsw_sp_port, lag_id, port_index);
4030        if (err)
4031                goto err_col_port_add;
4032        err = mlxsw_sp_lag_col_port_enable(mlxsw_sp_port, lag_id);
4033        if (err)
4034                goto err_col_port_enable;
4035
4036        mlxsw_core_lag_mapping_set(mlxsw_sp->core, lag_id, port_index,
4037                                   mlxsw_sp_port->local_port);
4038        mlxsw_sp_port->lag_id = lag_id;
4039        mlxsw_sp_port->lagged = 1;
4040        lag->ref_count++;
4041
4042        mlxsw_sp_port_pvid_vport_lag_join(mlxsw_sp_port, lag_id);
4043
4044        return 0;
4045
4046err_col_port_enable:
4047        mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
4048err_col_port_add:
4049        if (!lag->ref_count)
4050                mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
4051        return err;
4052}
4053
4054static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
4055                                    struct net_device *lag_dev)
4056{
4057        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4058        u16 lag_id = mlxsw_sp_port->lag_id;
4059        struct mlxsw_sp_upper *lag;
4060
4061        if (!mlxsw_sp_port->lagged)
4062                return;
4063        lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
4064        WARN_ON(lag->ref_count == 0);
4065
4066        mlxsw_sp_lag_col_port_disable(mlxsw_sp_port, lag_id);
4067        mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
4068
4069        if (mlxsw_sp_port->bridged) {
4070                mlxsw_sp_port_active_vlans_del(mlxsw_sp_port);
4071                mlxsw_sp_port_bridge_leave(mlxsw_sp_port);
4072        }
4073
4074        if (lag->ref_count == 1)
4075                mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
4076
4077        mlxsw_core_lag_mapping_clear(mlxsw_sp->core, lag_id,
4078                                     mlxsw_sp_port->local_port);
4079        mlxsw_sp_port->lagged = 0;
4080        lag->ref_count--;
4081
4082        mlxsw_sp_port_pvid_vport_lag_leave(mlxsw_sp_port);
4083}
4084
4085static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
4086                                      u16 lag_id)
4087{
4088        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4089        char sldr_pl[MLXSW_REG_SLDR_LEN];
4090
4091        mlxsw_reg_sldr_lag_add_port_pack(sldr_pl, lag_id,
4092                                         mlxsw_sp_port->local_port);
4093        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
4094}
4095
4096static int mlxsw_sp_lag_dist_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
4097                                         u16 lag_id)
4098{
4099        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4100        char sldr_pl[MLXSW_REG_SLDR_LEN];
4101
4102        mlxsw_reg_sldr_lag_remove_port_pack(sldr_pl, lag_id,
4103                                            mlxsw_sp_port->local_port);
4104        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
4105}
4106
4107static int mlxsw_sp_port_lag_tx_en_set(struct mlxsw_sp_port *mlxsw_sp_port,
4108                                       bool lag_tx_enabled)
4109{
4110        if (lag_tx_enabled)
4111                return mlxsw_sp_lag_dist_port_add(mlxsw_sp_port,
4112                                                  mlxsw_sp_port->lag_id);
4113        else
4114                return mlxsw_sp_lag_dist_port_remove(mlxsw_sp_port,
4115                                                     mlxsw_sp_port->lag_id);
4116}
4117
4118static int mlxsw_sp_port_lag_changed(struct mlxsw_sp_port *mlxsw_sp_port,
4119                                     struct netdev_lag_lower_state_info *info)
4120{
4121        return mlxsw_sp_port_lag_tx_en_set(mlxsw_sp_port, info->tx_enabled);
4122}
4123
4124static int mlxsw_sp_port_vlan_link(struct mlxsw_sp_port *mlxsw_sp_port,
4125                                   struct net_device *vlan_dev)
4126{
4127        struct mlxsw_sp_port *mlxsw_sp_vport;
4128        u16 vid = vlan_dev_vlan_id(vlan_dev);
4129
4130        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
4131        if (WARN_ON(!mlxsw_sp_vport))
4132                return -EINVAL;
4133
4134        mlxsw_sp_vport->dev = vlan_dev;
4135
4136        return 0;
4137}
4138
4139static void mlxsw_sp_port_vlan_unlink(struct mlxsw_sp_port *mlxsw_sp_port,
4140                                      struct net_device *vlan_dev)
4141{
4142        struct mlxsw_sp_port *mlxsw_sp_vport;
4143        u16 vid = vlan_dev_vlan_id(vlan_dev);
4144
4145        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
4146        if (WARN_ON(!mlxsw_sp_vport))
4147                return;
4148
4149        mlxsw_sp_vport->dev = mlxsw_sp_port->dev;
4150}
4151
4152static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
4153                                               unsigned long event, void *ptr)
4154{
4155        struct netdev_notifier_changeupper_info *info;
4156        struct mlxsw_sp_port *mlxsw_sp_port;
4157        struct net_device *upper_dev;
4158        struct mlxsw_sp *mlxsw_sp;
4159        int err = 0;
4160
4161        mlxsw_sp_port = netdev_priv(dev);
4162        mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4163        info = ptr;
4164
4165        switch (event) {
4166        case NETDEV_PRECHANGEUPPER:
4167                upper_dev = info->upper_dev;
4168                if (!is_vlan_dev(upper_dev) &&
4169                    !netif_is_lag_master(upper_dev) &&
4170                    !netif_is_bridge_master(upper_dev))
4171                        return -EINVAL;
4172                if (!info->linking)
4173                        break;
4174                /* HW limitation forbids to put ports to multiple bridges. */
4175                if (netif_is_bridge_master(upper_dev) &&
4176                    !mlxsw_sp_master_bridge_check(mlxsw_sp, upper_dev))
4177                        return -EINVAL;
4178                if (netif_is_lag_master(upper_dev) &&
4179                    !mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
4180                                               info->upper_info))
4181                        return -EINVAL;
4182                if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev))
4183                        return -EINVAL;
4184                if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) &&
4185                    !netif_is_lag_master(vlan_dev_real_dev(upper_dev)))
4186                        return -EINVAL;
4187                break;
4188        case NETDEV_CHANGEUPPER:
4189                upper_dev = info->upper_dev;
4190                if (is_vlan_dev(upper_dev)) {
4191                        if (info->linking)
4192                                err = mlxsw_sp_port_vlan_link(mlxsw_sp_port,
4193                                                              upper_dev);
4194                        else
4195                                 mlxsw_sp_port_vlan_unlink(mlxsw_sp_port,
4196                                                           upper_dev);
4197                } else if (netif_is_bridge_master(upper_dev)) {
4198                        if (info->linking)
4199                                err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
4200                                                                upper_dev);
4201                        else
4202                                mlxsw_sp_port_bridge_leave(mlxsw_sp_port);
4203                } else if (netif_is_lag_master(upper_dev)) {
4204                        if (info->linking)
4205                                err = mlxsw_sp_port_lag_join(mlxsw_sp_port,
4206                                                             upper_dev);
4207                        else
4208                                mlxsw_sp_port_lag_leave(mlxsw_sp_port,
4209                                                        upper_dev);
4210                } else {
4211                        err = -EINVAL;
4212                        WARN_ON(1);
4213                }
4214                break;
4215        }
4216
4217        return err;
4218}
4219
4220static int mlxsw_sp_netdevice_port_lower_event(struct net_device *dev,
4221                                               unsigned long event, void *ptr)
4222{
4223        struct netdev_notifier_changelowerstate_info *info;
4224        struct mlxsw_sp_port *mlxsw_sp_port;
4225        int err;
4226
4227        mlxsw_sp_port = netdev_priv(dev);
4228        info = ptr;
4229
4230        switch (event) {
4231        case NETDEV_CHANGELOWERSTATE:
4232                if (netif_is_lag_port(dev) && mlxsw_sp_port->lagged) {
4233                        err = mlxsw_sp_port_lag_changed(mlxsw_sp_port,
4234                                                        info->lower_state_info);
4235                        if (err)
4236                                netdev_err(dev, "Failed to reflect link aggregation lower state change\n");
4237                }
4238                break;
4239        }
4240
4241        return 0;
4242}
4243
4244static int mlxsw_sp_netdevice_port_event(struct net_device *dev,
4245                                         unsigned long event, void *ptr)
4246{
4247        switch (event) {
4248        case NETDEV_PRECHANGEUPPER:
4249        case NETDEV_CHANGEUPPER:
4250                return mlxsw_sp_netdevice_port_upper_event(dev, event, ptr);
4251        case NETDEV_CHANGELOWERSTATE:
4252                return mlxsw_sp_netdevice_port_lower_event(dev, event, ptr);
4253        }
4254
4255        return 0;
4256}
4257
4258static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
4259                                        unsigned long event, void *ptr)
4260{
4261        struct net_device *dev;
4262        struct list_head *iter;
4263        int ret;
4264
4265        netdev_for_each_lower_dev(lag_dev, dev, iter) {
4266                if (mlxsw_sp_port_dev_check(dev)) {
4267                        ret = mlxsw_sp_netdevice_port_event(dev, event, ptr);
4268                        if (ret)
4269                                return ret;
4270                }
4271        }
4272
4273        return 0;
4274}
4275
4276static int mlxsw_sp_master_bridge_vlan_link(struct mlxsw_sp *mlxsw_sp,
4277                                            struct net_device *vlan_dev)
4278{
4279        u16 fid = vlan_dev_vlan_id(vlan_dev);
4280        struct mlxsw_sp_fid *f;
4281
4282        f = mlxsw_sp_fid_find(mlxsw_sp, fid);
4283        if (!f) {
4284                f = mlxsw_sp_fid_create(mlxsw_sp, fid);
4285                if (IS_ERR(f))
4286                        return PTR_ERR(f);
4287        }
4288
4289        f->ref_count++;
4290
4291        return 0;
4292}
4293
4294static void mlxsw_sp_master_bridge_vlan_unlink(struct mlxsw_sp *mlxsw_sp,
4295                                               struct net_device *vlan_dev)
4296{
4297        u16 fid = vlan_dev_vlan_id(vlan_dev);
4298        struct mlxsw_sp_fid *f;
4299
4300        f = mlxsw_sp_fid_find(mlxsw_sp, fid);
4301        if (f && f->r)
4302                mlxsw_sp_rif_bridge_destroy(mlxsw_sp, f->r);
4303        if (f && --f->ref_count == 0)
4304                mlxsw_sp_fid_destroy(mlxsw_sp, f);
4305}
4306
4307static int mlxsw_sp_netdevice_bridge_event(struct net_device *br_dev,
4308                                           unsigned long event, void *ptr)
4309{
4310        struct netdev_notifier_changeupper_info *info;
4311        struct net_device *upper_dev;
4312        struct mlxsw_sp *mlxsw_sp;
4313        int err;
4314
4315        mlxsw_sp = mlxsw_sp_lower_get(br_dev);
4316        if (!mlxsw_sp)
4317                return 0;
4318        if (br_dev != mlxsw_sp->master_bridge.dev)
4319                return 0;
4320
4321        info = ptr;
4322
4323        switch (event) {
4324        case NETDEV_CHANGEUPPER:
4325                upper_dev = info->upper_dev;
4326                if (!is_vlan_dev(upper_dev))
4327                        break;
4328                if (info->linking) {
4329                        err = mlxsw_sp_master_bridge_vlan_link(mlxsw_sp,
4330                                                               upper_dev);
4331                        if (err)
4332                                return err;
4333                } else {
4334                        mlxsw_sp_master_bridge_vlan_unlink(mlxsw_sp, upper_dev);
4335                }
4336                break;
4337        }
4338
4339        return 0;
4340}
4341
4342static u16 mlxsw_sp_avail_vfid_get(const struct mlxsw_sp *mlxsw_sp)
4343{
4344        return find_first_zero_bit(mlxsw_sp->vfids.mapped,
4345                                   MLXSW_SP_VFID_MAX);
4346}
4347
4348static int mlxsw_sp_vfid_op(struct mlxsw_sp *mlxsw_sp, u16 fid, bool create)
4349{
4350        char sfmr_pl[MLXSW_REG_SFMR_LEN];
4351
4352        mlxsw_reg_sfmr_pack(sfmr_pl, !create, fid, 0);
4353        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
4354}
4355
4356static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport);
4357
4358static struct mlxsw_sp_fid *mlxsw_sp_vfid_create(struct mlxsw_sp *mlxsw_sp,
4359                                                 struct net_device *br_dev)
4360{
4361        struct device *dev = mlxsw_sp->bus_info->dev;
4362        struct mlxsw_sp_fid *f;
4363        u16 vfid, fid;
4364        int err;
4365
4366        vfid = mlxsw_sp_avail_vfid_get(mlxsw_sp);
4367        if (vfid == MLXSW_SP_VFID_MAX) {
4368                dev_err(dev, "No available vFIDs\n");
4369                return ERR_PTR(-ERANGE);
4370        }
4371
4372        fid = mlxsw_sp_vfid_to_fid(vfid);
4373        err = mlxsw_sp_vfid_op(mlxsw_sp, fid, true);
4374        if (err) {
4375                dev_err(dev, "Failed to create FID=%d\n", fid);
4376                return ERR_PTR(err);
4377        }
4378
4379        f = kzalloc(sizeof(*f), GFP_KERNEL);
4380        if (!f)
4381                goto err_allocate_vfid;
4382
4383        f->leave = mlxsw_sp_vport_vfid_leave;
4384        f->fid = fid;
4385        f->dev = br_dev;
4386
4387        list_add(&f->list, &mlxsw_sp->vfids.list);
4388        set_bit(vfid, mlxsw_sp->vfids.mapped);
4389
4390        return f;
4391
4392err_allocate_vfid:
4393        mlxsw_sp_vfid_op(mlxsw_sp, fid, false);
4394        return ERR_PTR(-ENOMEM);
4395}
4396
4397static void mlxsw_sp_vfid_destroy(struct mlxsw_sp *mlxsw_sp,
4398                                  struct mlxsw_sp_fid *f)
4399{
4400        u16 vfid = mlxsw_sp_fid_to_vfid(f->fid);
4401        u16 fid = f->fid;
4402
4403        clear_bit(vfid, mlxsw_sp->vfids.mapped);
4404        list_del(&f->list);
4405
4406        if (f->r)
4407                mlxsw_sp_rif_bridge_destroy(mlxsw_sp, f->r);
4408
4409        kfree(f);
4410
4411        mlxsw_sp_vfid_op(mlxsw_sp, fid, false);
4412}
4413
4414static int mlxsw_sp_vport_fid_map(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
4415                                  bool valid)
4416{
4417        enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
4418        u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
4419
4420        return mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport, mt, valid, fid,
4421                                            vid);
4422}
4423
4424static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport,
4425                                    struct net_device *br_dev)
4426{
4427        struct mlxsw_sp_fid *f;
4428        int err;
4429
4430        f = mlxsw_sp_vfid_find(mlxsw_sp_vport->mlxsw_sp, br_dev);
4431        if (!f) {
4432                f = mlxsw_sp_vfid_create(mlxsw_sp_vport->mlxsw_sp, br_dev);
4433                if (IS_ERR(f))
4434                        return PTR_ERR(f);
4435        }
4436
4437        err = mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, true);
4438        if (err)
4439                goto err_vport_flood_set;
4440
4441        err = mlxsw_sp_vport_fid_map(mlxsw_sp_vport, f->fid, true);
4442        if (err)
4443                goto err_vport_fid_map;
4444
4445        mlxsw_sp_vport_fid_set(mlxsw_sp_vport, f);
4446        f->ref_count++;
4447
4448        netdev_dbg(mlxsw_sp_vport->dev, "Joined FID=%d\n", f->fid);
4449
4450        return 0;
4451
4452err_vport_fid_map:
4453        mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false);
4454err_vport_flood_set:
4455        if (!f->ref_count)
4456                mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f);
4457        return err;
4458}
4459
4460static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
4461{
4462        struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
4463
4464        netdev_dbg(mlxsw_sp_vport->dev, "Left FID=%d\n", f->fid);
4465
4466        mlxsw_sp_vport_fid_map(mlxsw_sp_vport, f->fid, false);
4467
4468        mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false);
4469
4470        mlxsw_sp_port_fdb_flush(mlxsw_sp_vport, f->fid);
4471
4472        mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
4473        if (--f->ref_count == 0)
4474                mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f);
4475}
4476
4477static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport,
4478                                      struct net_device *br_dev)
4479{
4480        struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
4481        u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
4482        struct net_device *dev = mlxsw_sp_vport->dev;
4483        int err;
4484
4485        if (f && !WARN_ON(!f->leave))
4486                f->leave(mlxsw_sp_vport);
4487
4488        err = mlxsw_sp_vport_vfid_join(mlxsw_sp_vport, br_dev);
4489        if (err) {
4490                netdev_err(dev, "Failed to join vFID\n");
4491                return err;
4492        }
4493
4494        err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
4495        if (err) {
4496                netdev_err(dev, "Failed to enable learning\n");
4497                goto err_port_vid_learning_set;
4498        }
4499
4500        mlxsw_sp_vport->learning = 1;
4501        mlxsw_sp_vport->learning_sync = 1;
4502        mlxsw_sp_vport->uc_flood = 1;
4503        mlxsw_sp_vport->bridged = 1;
4504
4505        return 0;
4506
4507err_port_vid_learning_set:
4508        mlxsw_sp_vport_vfid_leave(mlxsw_sp_vport);
4509        return err;
4510}
4511
4512static void mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
4513{
4514        u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
4515
4516        mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false);
4517
4518        mlxsw_sp_vport_vfid_leave(mlxsw_sp_vport);
4519
4520        mlxsw_sp_vport->learning = 0;
4521        mlxsw_sp_vport->learning_sync = 0;
4522        mlxsw_sp_vport->uc_flood = 0;
4523        mlxsw_sp_vport->bridged = 0;
4524}
4525
4526static bool
4527mlxsw_sp_port_master_bridge_check(const struct mlxsw_sp_port *mlxsw_sp_port,
4528                                  const struct net_device *br_dev)
4529{
4530        struct mlxsw_sp_port *mlxsw_sp_vport;
4531
4532        list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list,
4533                            vport.list) {
4534                struct net_device *dev = mlxsw_sp_vport_dev_get(mlxsw_sp_vport);
4535
4536                if (dev && dev == br_dev)
4537                        return false;
4538        }
4539
4540        return true;
4541}
4542
4543static int mlxsw_sp_netdevice_vport_event(struct net_device *dev,
4544                                          unsigned long event, void *ptr,
4545                                          u16 vid)
4546{
4547        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
4548        struct netdev_notifier_changeupper_info *info = ptr;
4549        struct mlxsw_sp_port *mlxsw_sp_vport;
4550        struct net_device *upper_dev;
4551        int err = 0;
4552
4553        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
4554
4555        switch (event) {
4556        case NETDEV_PRECHANGEUPPER:
4557                upper_dev = info->upper_dev;
4558                if (!netif_is_bridge_master(upper_dev))
4559                        return -EINVAL;
4560                if (!info->linking)
4561                        break;
4562                /* We can't have multiple VLAN interfaces configured on
4563                 * the same port and being members in the same bridge.
4564                 */
4565                if (!mlxsw_sp_port_master_bridge_check(mlxsw_sp_port,
4566                                                       upper_dev))
4567                        return -EINVAL;
4568                break;
4569        case NETDEV_CHANGEUPPER:
4570                upper_dev = info->upper_dev;
4571                if (info->linking) {
4572                        if (WARN_ON(!mlxsw_sp_vport))
4573                                return -EINVAL;
4574                        err = mlxsw_sp_vport_bridge_join(mlxsw_sp_vport,
4575                                                         upper_dev);
4576                } else {
4577                        if (!mlxsw_sp_vport)
4578                                return 0;
4579                        mlxsw_sp_vport_bridge_leave(mlxsw_sp_vport);
4580                }
4581        }
4582
4583        return err;
4584}
4585
4586static int mlxsw_sp_netdevice_lag_vport_event(struct net_device *lag_dev,
4587                                              unsigned long event, void *ptr,
4588                                              u16 vid)
4589{
4590        struct net_device *dev;
4591        struct list_head *iter;
4592        int ret;
4593
4594        netdev_for_each_lower_dev(lag_dev, dev, iter) {
4595                if (mlxsw_sp_port_dev_check(dev)) {
4596                        ret = mlxsw_sp_netdevice_vport_event(dev, event, ptr,
4597                                                             vid);
4598                        if (ret)
4599                                return ret;
4600                }
4601        }
4602
4603        return 0;
4604}
4605
4606static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
4607                                         unsigned long event, void *ptr)
4608{
4609        struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
4610        u16 vid = vlan_dev_vlan_id(vlan_dev);
4611
4612        if (mlxsw_sp_port_dev_check(real_dev))
4613                return mlxsw_sp_netdevice_vport_event(real_dev, event, ptr,
4614                                                      vid);
4615        else if (netif_is_lag_master(real_dev))
4616                return mlxsw_sp_netdevice_lag_vport_event(real_dev, event, ptr,
4617                                                          vid);
4618
4619        return 0;
4620}
4621
4622static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
4623                                    unsigned long event, void *ptr)
4624{
4625        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
4626        int err = 0;
4627
4628        if (event == NETDEV_CHANGEADDR || event == NETDEV_CHANGEMTU)
4629                err = mlxsw_sp_netdevice_router_port_event(dev);
4630        else if (mlxsw_sp_port_dev_check(dev))
4631                err = mlxsw_sp_netdevice_port_event(dev, event, ptr);
4632        else if (netif_is_lag_master(dev))
4633                err = mlxsw_sp_netdevice_lag_event(dev, event, ptr);
4634        else if (netif_is_bridge_master(dev))
4635                err = mlxsw_sp_netdevice_bridge_event(dev, event, ptr);
4636        else if (is_vlan_dev(dev))
4637                err = mlxsw_sp_netdevice_vlan_event(dev, event, ptr);
4638
4639        return notifier_from_errno(err);
4640}
4641
4642static struct notifier_block mlxsw_sp_netdevice_nb __read_mostly = {
4643        .notifier_call = mlxsw_sp_netdevice_event,
4644};
4645
4646static struct notifier_block mlxsw_sp_inetaddr_nb __read_mostly = {
4647        .notifier_call = mlxsw_sp_inetaddr_event,
4648        .priority = 10, /* Must be called before FIB notifier block */
4649};
4650
4651static struct notifier_block mlxsw_sp_router_netevent_nb __read_mostly = {
4652        .notifier_call = mlxsw_sp_router_netevent_event,
4653};
4654
4655static int __init mlxsw_sp_module_init(void)
4656{
4657        int err;
4658
4659        register_netdevice_notifier(&mlxsw_sp_netdevice_nb);
4660        register_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
4661        register_netevent_notifier(&mlxsw_sp_router_netevent_nb);
4662
4663        err = mlxsw_core_driver_register(&mlxsw_sp_driver);
4664        if (err)
4665                goto err_core_driver_register;
4666        return 0;
4667
4668err_core_driver_register:
4669        unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
4670        unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
4671        unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb);
4672        return err;
4673}
4674
4675static void __exit mlxsw_sp_module_exit(void)
4676{
4677        mlxsw_core_driver_unregister(&mlxsw_sp_driver);
4678        unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
4679        unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
4680        unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb);
4681}
4682
4683module_init(mlxsw_sp_module_init);
4684module_exit(mlxsw_sp_module_exit);
4685
4686MODULE_LICENSE("Dual BSD/GPL");
4687MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
4688MODULE_DESCRIPTION("Mellanox Spectrum driver");
4689MODULE_MLXSW_DRIVER_ALIAS(MLXSW_DEVICE_KIND_SPECTRUM);
4690