aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c735
1 files changed, 593 insertions, 142 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index adc6ab2cf429..f84b9c02fcc5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1,38 +1,5 @@
1/* 1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 * drivers/net/ethernet/mellanox/mlxsw/spectrum.c 2/* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
3 * Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2015-2017 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 3
37#include <linux/kernel.h> 4#include <linux/kernel.h>
38#include <linux/module.h> 5#include <linux/module.h>
@@ -54,6 +21,7 @@
54#include <linux/dcbnl.h> 21#include <linux/dcbnl.h>
55#include <linux/inetdevice.h> 22#include <linux/inetdevice.h>
56#include <linux/netlink.h> 23#include <linux/netlink.h>
24#include <linux/random.h>
57#include <net/switchdev.h> 25#include <net/switchdev.h>
58#include <net/pkt_cls.h> 26#include <net/pkt_cls.h>
59#include <net/tc_act/tc_mirred.h> 27#include <net/tc_act/tc_mirred.h>
@@ -74,17 +42,27 @@
74#include "spectrum_span.h" 42#include "spectrum_span.h"
75#include "../mlxfw/mlxfw.h" 43#include "../mlxfw/mlxfw.h"
76 44
77#define MLXSW_FWREV_MAJOR 13 45#define MLXSW_SP_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
78#define MLXSW_FWREV_MINOR 1620
79#define MLXSW_FWREV_SUBMINOR 192
80#define MLXSW_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
81 46
82#define MLXSW_SP_FW_FILENAME \ 47#define MLXSW_SP1_FWREV_MAJOR 13
83 "mellanox/mlxsw_spectrum-" __stringify(MLXSW_FWREV_MAJOR) \ 48#define MLXSW_SP1_FWREV_MINOR 1703
84 "." __stringify(MLXSW_FWREV_MINOR) \ 49#define MLXSW_SP1_FWREV_SUBMINOR 4
85 "." __stringify(MLXSW_FWREV_SUBMINOR) ".mfa2" 50#define MLXSW_SP1_FWREV_CAN_RESET_MINOR 1702
86 51
87static const char mlxsw_sp_driver_name[] = "mlxsw_spectrum"; 52static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = {
53 .major = MLXSW_SP1_FWREV_MAJOR,
54 .minor = MLXSW_SP1_FWREV_MINOR,
55 .subminor = MLXSW_SP1_FWREV_SUBMINOR,
56 .can_reset_minor = MLXSW_SP1_FWREV_CAN_RESET_MINOR,
57};
58
59#define MLXSW_SP1_FW_FILENAME \
60 "mellanox/mlxsw_spectrum-" __stringify(MLXSW_SP1_FWREV_MAJOR) \
61 "." __stringify(MLXSW_SP1_FWREV_MINOR) \
62 "." __stringify(MLXSW_SP1_FWREV_SUBMINOR) ".mfa2"
63
64static const char mlxsw_sp1_driver_name[] = "mlxsw_spectrum";
65static const char mlxsw_sp2_driver_name[] = "mlxsw_spectrum2";
88static const char mlxsw_sp_driver_version[] = "1.0"; 66static const char mlxsw_sp_driver_version[] = "1.0";
89 67
90/* tx_hdr_version 68/* tx_hdr_version
@@ -331,42 +309,65 @@ static int mlxsw_sp_firmware_flash(struct mlxsw_sp *mlxsw_sp,
331 }, 309 },
332 .mlxsw_sp = mlxsw_sp 310 .mlxsw_sp = mlxsw_sp
333 }; 311 };
312 int err;
313
314 mlxsw_core_fw_flash_start(mlxsw_sp->core);
315 err = mlxfw_firmware_flash(&mlxsw_sp_mlxfw_dev.mlxfw_dev, firmware);
316 mlxsw_core_fw_flash_end(mlxsw_sp->core);
334 317
335 return mlxfw_firmware_flash(&mlxsw_sp_mlxfw_dev.mlxfw_dev, firmware); 318 return err;
336} 319}
337 320
338static int mlxsw_sp_fw_rev_validate(struct mlxsw_sp *mlxsw_sp) 321static int mlxsw_sp_fw_rev_validate(struct mlxsw_sp *mlxsw_sp)
339{ 322{
340 const struct mlxsw_fw_rev *rev = &mlxsw_sp->bus_info->fw_rev; 323 const struct mlxsw_fw_rev *rev = &mlxsw_sp->bus_info->fw_rev;
324 const struct mlxsw_fw_rev *req_rev = mlxsw_sp->req_rev;
325 const char *fw_filename = mlxsw_sp->fw_filename;
341 const struct firmware *firmware; 326 const struct firmware *firmware;
342 int err; 327 int err;
343 328
329 /* Don't check if driver does not require it */
330 if (!req_rev || !fw_filename)
331 return 0;
332
344 /* Validate driver & FW are compatible */ 333 /* Validate driver & FW are compatible */
345 if (rev->major != MLXSW_FWREV_MAJOR) { 334 if (rev->major != req_rev->major) {
346 WARN(1, "Mismatch in major FW version [%d:%d] is never expected; Please contact support\n", 335 WARN(1, "Mismatch in major FW version [%d:%d] is never expected; Please contact support\n",
347 rev->major, MLXSW_FWREV_MAJOR); 336 rev->major, req_rev->major);
348 return -EINVAL; 337 return -EINVAL;
349 } 338 }
350 if (MLXSW_FWREV_MINOR_TO_BRANCH(rev->minor) == 339 if (MLXSW_SP_FWREV_MINOR_TO_BRANCH(rev->minor) ==
351 MLXSW_FWREV_MINOR_TO_BRANCH(MLXSW_FWREV_MINOR)) 340 MLXSW_SP_FWREV_MINOR_TO_BRANCH(req_rev->minor) &&
341 (rev->minor > req_rev->minor ||
342 (rev->minor == req_rev->minor &&
343 rev->subminor >= req_rev->subminor)))
352 return 0; 344 return 0;
353 345
354 dev_info(mlxsw_sp->bus_info->dev, "The firmware version %d.%d.%d is incompatible with the driver\n", 346 dev_info(mlxsw_sp->bus_info->dev, "The firmware version %d.%d.%d is incompatible with the driver\n",
355 rev->major, rev->minor, rev->subminor); 347 rev->major, rev->minor, rev->subminor);
356 dev_info(mlxsw_sp->bus_info->dev, "Flashing firmware using file %s\n", 348 dev_info(mlxsw_sp->bus_info->dev, "Flashing firmware using file %s\n",
357 MLXSW_SP_FW_FILENAME); 349 fw_filename);
358 350
359 err = request_firmware_direct(&firmware, MLXSW_SP_FW_FILENAME, 351 err = request_firmware_direct(&firmware, fw_filename,
360 mlxsw_sp->bus_info->dev); 352 mlxsw_sp->bus_info->dev);
361 if (err) { 353 if (err) {
362 dev_err(mlxsw_sp->bus_info->dev, "Could not request firmware file %s\n", 354 dev_err(mlxsw_sp->bus_info->dev, "Could not request firmware file %s\n",
363 MLXSW_SP_FW_FILENAME); 355 fw_filename);
364 return err; 356 return err;
365 } 357 }
366 358
367 err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware); 359 err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware);
368 release_firmware(firmware); 360 release_firmware(firmware);
369 return err; 361 if (err)
362 dev_err(mlxsw_sp->bus_info->dev, "Could not upgrade firmware\n");
363
364 /* On FW flash success, tell the caller FW reset is needed
365 * if current FW supports it.
366 */
367 if (rev->minor >= req_rev->can_reset_minor)
368 return err ? err : -EAGAIN;
369 else
370 return 0;
370} 371}
371 372
372int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp, 373int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp,
@@ -441,29 +442,29 @@ static void mlxsw_sp_txhdr_construct(struct sk_buff *skb,
441 mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL); 442 mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL);
442} 443}
443 444
444int mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid, 445enum mlxsw_reg_spms_state mlxsw_sp_stp_spms_state(u8 state)
445 u8 state)
446{ 446{
447 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
448 enum mlxsw_reg_spms_state spms_state;
449 char *spms_pl;
450 int err;
451
452 switch (state) { 447 switch (state) {
453 case BR_STATE_FORWARDING: 448 case BR_STATE_FORWARDING:
454 spms_state = MLXSW_REG_SPMS_STATE_FORWARDING; 449 return MLXSW_REG_SPMS_STATE_FORWARDING;
455 break;
456 case BR_STATE_LEARNING: 450 case BR_STATE_LEARNING:
457 spms_state = MLXSW_REG_SPMS_STATE_LEARNING; 451 return MLXSW_REG_SPMS_STATE_LEARNING;
458 break;
459 case BR_STATE_LISTENING: /* fall-through */ 452 case BR_STATE_LISTENING: /* fall-through */
460 case BR_STATE_DISABLED: /* fall-through */ 453 case BR_STATE_DISABLED: /* fall-through */
461 case BR_STATE_BLOCKING: 454 case BR_STATE_BLOCKING:
462 spms_state = MLXSW_REG_SPMS_STATE_DISCARDING; 455 return MLXSW_REG_SPMS_STATE_DISCARDING;
463 break;
464 default: 456 default:
465 BUG(); 457 BUG();
466 } 458 }
459}
460
461int mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
462 u8 state)
463{
464 enum mlxsw_reg_spms_state spms_state = mlxsw_sp_stp_spms_state(state);
465 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
466 char *spms_pl;
467 int err;
467 468
468 spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL); 469 spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL);
469 if (!spms_pl) 470 if (!spms_pl)
@@ -1238,21 +1239,10 @@ static int mlxsw_sp_port_get_phys_port_name(struct net_device *dev, char *name,
1238 size_t len) 1239 size_t len)
1239{ 1240{
1240 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 1241 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1241 u8 module = mlxsw_sp_port->mapping.module;
1242 u8 width = mlxsw_sp_port->mapping.width;
1243 u8 lane = mlxsw_sp_port->mapping.lane;
1244 int err;
1245
1246 if (!mlxsw_sp_port->split)
1247 err = snprintf(name, len, "p%d", module + 1);
1248 else
1249 err = snprintf(name, len, "p%ds%d", module + 1,
1250 lane / width);
1251
1252 if (err >= len)
1253 return -EINVAL;
1254 1242
1255 return 0; 1243 return mlxsw_core_port_get_phys_port_name(mlxsw_sp_port->mlxsw_sp->core,
1244 mlxsw_sp_port->local_port,
1245 name, len);
1256} 1246}
1257 1247
1258static struct mlxsw_sp_port_mall_tc_entry * 1248static struct mlxsw_sp_port_mall_tc_entry *
@@ -1365,8 +1355,7 @@ static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
1365 return -ENOMEM; 1355 return -ENOMEM;
1366 mall_tc_entry->cookie = f->cookie; 1356 mall_tc_entry->cookie = f->cookie;
1367 1357
1368 tcf_exts_to_list(f->exts, &actions); 1358 a = tcf_exts_first_action(f->exts);
1369 a = list_first_entry(&actions, struct tc_action, list);
1370 1359
1371 if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) { 1360 if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) {
1372 struct mlxsw_sp_port_mall_mirror_tc_entry *mirror; 1361 struct mlxsw_sp_port_mall_mirror_tc_entry *mirror;
@@ -1452,6 +1441,11 @@ mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_acl_block *acl_block,
1452 return 0; 1441 return 0;
1453 case TC_CLSFLOWER_STATS: 1442 case TC_CLSFLOWER_STATS:
1454 return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f); 1443 return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f);
1444 case TC_CLSFLOWER_TMPLT_CREATE:
1445 return mlxsw_sp_flower_tmplt_create(mlxsw_sp, acl_block, f);
1446 case TC_CLSFLOWER_TMPLT_DESTROY:
1447 mlxsw_sp_flower_tmplt_destroy(mlxsw_sp, acl_block, f);
1448 return 0;
1455 default: 1449 default:
1456 return -EOPNOTSUPP; 1450 return -EOPNOTSUPP;
1457 } 1451 }
@@ -1514,7 +1508,8 @@ static int mlxsw_sp_setup_tc_block_cb_flower(enum tc_setup_type type,
1514 1508
1515static int 1509static int
1516mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port, 1510mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
1517 struct tcf_block *block, bool ingress) 1511 struct tcf_block *block, bool ingress,
1512 struct netlink_ext_ack *extack)
1518{ 1513{
1519 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 1514 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1520 struct mlxsw_sp_acl_block *acl_block; 1515 struct mlxsw_sp_acl_block *acl_block;
@@ -1529,7 +1524,7 @@ mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
1529 return -ENOMEM; 1524 return -ENOMEM;
1530 block_cb = __tcf_block_cb_register(block, 1525 block_cb = __tcf_block_cb_register(block,
1531 mlxsw_sp_setup_tc_block_cb_flower, 1526 mlxsw_sp_setup_tc_block_cb_flower,
1532 mlxsw_sp, acl_block); 1527 mlxsw_sp, acl_block, extack);
1533 if (IS_ERR(block_cb)) { 1528 if (IS_ERR(block_cb)) {
1534 err = PTR_ERR(block_cb); 1529 err = PTR_ERR(block_cb);
1535 goto err_cb_register; 1530 goto err_cb_register;
@@ -1552,7 +1547,7 @@ mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
1552 1547
1553err_block_bind: 1548err_block_bind:
1554 if (!tcf_block_cb_decref(block_cb)) { 1549 if (!tcf_block_cb_decref(block_cb)) {
1555 __tcf_block_cb_unregister(block_cb); 1550 __tcf_block_cb_unregister(block, block_cb);
1556err_cb_register: 1551err_cb_register:
1557 mlxsw_sp_acl_block_destroy(acl_block); 1552 mlxsw_sp_acl_block_destroy(acl_block);
1558 } 1553 }
@@ -1582,7 +1577,7 @@ mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
1582 err = mlxsw_sp_acl_block_unbind(mlxsw_sp, acl_block, 1577 err = mlxsw_sp_acl_block_unbind(mlxsw_sp, acl_block,
1583 mlxsw_sp_port, ingress); 1578 mlxsw_sp_port, ingress);
1584 if (!err && !tcf_block_cb_decref(block_cb)) { 1579 if (!err && !tcf_block_cb_decref(block_cb)) {
1585 __tcf_block_cb_unregister(block_cb); 1580 __tcf_block_cb_unregister(block, block_cb);
1586 mlxsw_sp_acl_block_destroy(acl_block); 1581 mlxsw_sp_acl_block_destroy(acl_block);
1587 } 1582 }
1588} 1583}
@@ -1607,11 +1602,12 @@ static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
1607 switch (f->command) { 1602 switch (f->command) {
1608 case TC_BLOCK_BIND: 1603 case TC_BLOCK_BIND:
1609 err = tcf_block_cb_register(f->block, cb, mlxsw_sp_port, 1604 err = tcf_block_cb_register(f->block, cb, mlxsw_sp_port,
1610 mlxsw_sp_port); 1605 mlxsw_sp_port, f->extack);
1611 if (err) 1606 if (err)
1612 return err; 1607 return err;
1613 err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port, 1608 err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port,
1614 f->block, ingress); 1609 f->block, ingress,
1610 f->extack);
1615 if (err) { 1611 if (err) {
1616 tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port); 1612 tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port);
1617 return err; 1613 return err;
@@ -1723,7 +1719,8 @@ static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
1723 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 1719 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1724 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 1720 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1725 1721
1726 strlcpy(drvinfo->driver, mlxsw_sp_driver_name, sizeof(drvinfo->driver)); 1722 strlcpy(drvinfo->driver, mlxsw_sp->bus_info->device_kind,
1723 sizeof(drvinfo->driver));
1727 strlcpy(drvinfo->version, mlxsw_sp_driver_version, 1724 strlcpy(drvinfo->version, mlxsw_sp_driver_version,
1728 sizeof(drvinfo->version)); 1725 sizeof(drvinfo->version));
1729 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), 1726 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
@@ -1884,6 +1881,52 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = {
1884 1881
1885#define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats) 1882#define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats)
1886 1883
1884static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2819_stats[] = {
1885 {
1886 .str = "ether_pkts64octets",
1887 .getter = mlxsw_reg_ppcnt_ether_stats_pkts64octets_get,
1888 },
1889 {
1890 .str = "ether_pkts65to127octets",
1891 .getter = mlxsw_reg_ppcnt_ether_stats_pkts65to127octets_get,
1892 },
1893 {
1894 .str = "ether_pkts128to255octets",
1895 .getter = mlxsw_reg_ppcnt_ether_stats_pkts128to255octets_get,
1896 },
1897 {
1898 .str = "ether_pkts256to511octets",
1899 .getter = mlxsw_reg_ppcnt_ether_stats_pkts256to511octets_get,
1900 },
1901 {
1902 .str = "ether_pkts512to1023octets",
1903 .getter = mlxsw_reg_ppcnt_ether_stats_pkts512to1023octets_get,
1904 },
1905 {
1906 .str = "ether_pkts1024to1518octets",
1907 .getter = mlxsw_reg_ppcnt_ether_stats_pkts1024to1518octets_get,
1908 },
1909 {
1910 .str = "ether_pkts1519to2047octets",
1911 .getter = mlxsw_reg_ppcnt_ether_stats_pkts1519to2047octets_get,
1912 },
1913 {
1914 .str = "ether_pkts2048to4095octets",
1915 .getter = mlxsw_reg_ppcnt_ether_stats_pkts2048to4095octets_get,
1916 },
1917 {
1918 .str = "ether_pkts4096to8191octets",
1919 .getter = mlxsw_reg_ppcnt_ether_stats_pkts4096to8191octets_get,
1920 },
1921 {
1922 .str = "ether_pkts8192to10239octets",
1923 .getter = mlxsw_reg_ppcnt_ether_stats_pkts8192to10239octets_get,
1924 },
1925};
1926
1927#define MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN \
1928 ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2819_stats)
1929
1887static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = { 1930static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = {
1888 { 1931 {
1889 .str = "rx_octets_prio", 1932 .str = "rx_octets_prio",
@@ -1936,9 +1979,11 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
1936#define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats) 1979#define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats)
1937 1980
1938#define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \ 1981#define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \
1939 (MLXSW_SP_PORT_HW_PRIO_STATS_LEN + \ 1982 MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN + \
1940 MLXSW_SP_PORT_HW_TC_STATS_LEN) * \ 1983 (MLXSW_SP_PORT_HW_PRIO_STATS_LEN * \
1941 IEEE_8021QAZ_MAX_TCS) 1984 IEEE_8021QAZ_MAX_TCS) + \
1985 (MLXSW_SP_PORT_HW_TC_STATS_LEN * \
1986 TC_MAX_QUEUE))
1942 1987
1943static void mlxsw_sp_port_get_prio_strings(u8 **p, int prio) 1988static void mlxsw_sp_port_get_prio_strings(u8 **p, int prio)
1944{ 1989{
@@ -1975,11 +2020,16 @@ static void mlxsw_sp_port_get_strings(struct net_device *dev,
1975 ETH_GSTRING_LEN); 2020 ETH_GSTRING_LEN);
1976 p += ETH_GSTRING_LEN; 2021 p += ETH_GSTRING_LEN;
1977 } 2022 }
2023 for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN; i++) {
2024 memcpy(p, mlxsw_sp_port_hw_rfc_2819_stats[i].str,
2025 ETH_GSTRING_LEN);
2026 p += ETH_GSTRING_LEN;
2027 }
1978 2028
1979 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 2029 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
1980 mlxsw_sp_port_get_prio_strings(&p, i); 2030 mlxsw_sp_port_get_prio_strings(&p, i);
1981 2031
1982 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 2032 for (i = 0; i < TC_MAX_QUEUE; i++)
1983 mlxsw_sp_port_get_tc_strings(&p, i); 2033 mlxsw_sp_port_get_tc_strings(&p, i);
1984 2034
1985 break; 2035 break;
@@ -2014,10 +2064,14 @@ mlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats,
2014 int *p_len, enum mlxsw_reg_ppcnt_grp grp) 2064 int *p_len, enum mlxsw_reg_ppcnt_grp grp)
2015{ 2065{
2016 switch (grp) { 2066 switch (grp) {
2017 case MLXSW_REG_PPCNT_IEEE_8023_CNT: 2067 case MLXSW_REG_PPCNT_IEEE_8023_CNT:
2018 *p_hw_stats = mlxsw_sp_port_hw_stats; 2068 *p_hw_stats = mlxsw_sp_port_hw_stats;
2019 *p_len = MLXSW_SP_PORT_HW_STATS_LEN; 2069 *p_len = MLXSW_SP_PORT_HW_STATS_LEN;
2020 break; 2070 break;
2071 case MLXSW_REG_PPCNT_RFC_2819_CNT:
2072 *p_hw_stats = mlxsw_sp_port_hw_rfc_2819_stats;
2073 *p_len = MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
2074 break;
2021 case MLXSW_REG_PPCNT_PRIO_CNT: 2075 case MLXSW_REG_PPCNT_PRIO_CNT:
2022 *p_hw_stats = mlxsw_sp_port_hw_prio_stats; 2076 *p_hw_stats = mlxsw_sp_port_hw_prio_stats;
2023 *p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN; 2077 *p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
@@ -2067,6 +2121,11 @@ static void mlxsw_sp_port_get_stats(struct net_device *dev,
2067 data, data_index); 2121 data, data_index);
2068 data_index = MLXSW_SP_PORT_HW_STATS_LEN; 2122 data_index = MLXSW_SP_PORT_HW_STATS_LEN;
2069 2123
2124 /* RFC 2819 Counters */
2125 __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2819_CNT, 0,
2126 data, data_index);
2127 data_index += MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
2128
2070 /* Per-Priority Counters */ 2129 /* Per-Priority Counters */
2071 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 2130 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
2072 __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_PRIO_CNT, i, 2131 __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_PRIO_CNT, i,
@@ -2075,7 +2134,7 @@ static void mlxsw_sp_port_get_stats(struct net_device *dev,
2075 } 2134 }
2076 2135
2077 /* Per-TC Counters */ 2136 /* Per-TC Counters */
2078 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 2137 for (i = 0; i < TC_MAX_QUEUE; i++) {
2079 __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_TC_CNT, i, 2138 __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_TC_CNT, i,
2080 data, data_index); 2139 data, data_index);
2081 data_index += MLXSW_SP_PORT_HW_TC_STATS_LEN; 2140 data_index += MLXSW_SP_PORT_HW_TC_STATS_LEN;
@@ -2686,6 +2745,21 @@ int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
2686 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl); 2745 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
2687} 2746}
2688 2747
2748static int mlxsw_sp_port_min_bw_set(struct mlxsw_sp_port *mlxsw_sp_port,
2749 enum mlxsw_reg_qeec_hr hr, u8 index,
2750 u8 next_index, u32 minrate)
2751{
2752 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2753 char qeec_pl[MLXSW_REG_QEEC_LEN];
2754
2755 mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
2756 next_index);
2757 mlxsw_reg_qeec_mise_set(qeec_pl, true);
2758 mlxsw_reg_qeec_min_shaper_rate_set(qeec_pl, minrate);
2759
2760 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
2761}
2762
2689int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port, 2763int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port,
2690 u8 switch_prio, u8 tclass) 2764 u8 switch_prio, u8 tclass)
2691{ 2765{
@@ -2722,9 +2796,16 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
2722 false, 0); 2796 false, 0);
2723 if (err) 2797 if (err)
2724 return err; 2798 return err;
2799
2800 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
2801 MLXSW_REG_QEEC_HIERARCY_TC,
2802 i + 8, i,
2803 false, 0);
2804 if (err)
2805 return err;
2725 } 2806 }
2726 2807
2727 /* Make sure the max shaper is disabled in all hierarcies that 2808 /* Make sure the max shaper is disabled in all hierarchies that
2728 * support it. 2809 * support it.
2729 */ 2810 */
2730 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port, 2811 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
@@ -2747,6 +2828,23 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
2747 MLXSW_REG_QEEC_MAS_DIS); 2828 MLXSW_REG_QEEC_MAS_DIS);
2748 if (err) 2829 if (err)
2749 return err; 2830 return err;
2831
2832 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
2833 MLXSW_REG_QEEC_HIERARCY_TC,
2834 i + 8, i,
2835 MLXSW_REG_QEEC_MAS_DIS);
2836 if (err)
2837 return err;
2838 }
2839
2840 /* Configure the min shaper for multicast TCs. */
2841 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
2842 err = mlxsw_sp_port_min_bw_set(mlxsw_sp_port,
2843 MLXSW_REG_QEEC_HIERARCY_TC,
2844 i + 8, i,
2845 MLXSW_REG_QEEC_MIS_MIN);
2846 if (err)
2847 return err;
2750 } 2848 }
2751 2849
2752 /* Map all priorities to traffic class 0. */ 2850 /* Map all priorities to traffic class 0. */
@@ -2759,6 +2857,16 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
2759 return 0; 2857 return 0;
2760} 2858}
2761 2859
2860static int mlxsw_sp_port_tc_mc_mode_set(struct mlxsw_sp_port *mlxsw_sp_port,
2861 bool enable)
2862{
2863 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2864 char qtctm_pl[MLXSW_REG_QTCTM_LEN];
2865
2866 mlxsw_reg_qtctm_pack(qtctm_pl, mlxsw_sp_port->local_port, enable);
2867 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtctm), qtctm_pl);
2868}
2869
2762static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, 2870static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2763 bool split, u8 module, u8 width, u8 lane) 2871 bool split, u8 module, u8 width, u8 lane)
2764{ 2872{
@@ -2887,6 +2995,13 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2887 goto err_port_ets_init; 2995 goto err_port_ets_init;
2888 } 2996 }
2889 2997
2998 err = mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, true);
2999 if (err) {
3000 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize TC MC mode\n",
3001 mlxsw_sp_port->local_port);
3002 goto err_port_tc_mc_mode;
3003 }
3004
2890 /* ETS and buffers must be initialized before DCB. */ 3005 /* ETS and buffers must be initialized before DCB. */
2891 err = mlxsw_sp_port_dcb_init(mlxsw_sp_port); 3006 err = mlxsw_sp_port_dcb_init(mlxsw_sp_port);
2892 if (err) { 3007 if (err) {
@@ -2909,6 +3024,13 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2909 goto err_port_qdiscs_init; 3024 goto err_port_qdiscs_init;
2910 } 3025 }
2911 3026
3027 err = mlxsw_sp_port_nve_init(mlxsw_sp_port);
3028 if (err) {
3029 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize NVE\n",
3030 mlxsw_sp_port->local_port);
3031 goto err_port_nve_init;
3032 }
3033
2912 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_get(mlxsw_sp_port, 1); 3034 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_get(mlxsw_sp_port, 1);
2913 if (IS_ERR(mlxsw_sp_port_vlan)) { 3035 if (IS_ERR(mlxsw_sp_port_vlan)) {
2914 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to create VID 1\n", 3036 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to create VID 1\n",
@@ -2927,8 +3049,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2927 } 3049 }
2928 3050
2929 mlxsw_core_port_eth_set(mlxsw_sp->core, mlxsw_sp_port->local_port, 3051 mlxsw_core_port_eth_set(mlxsw_sp->core, mlxsw_sp_port->local_port,
2930 mlxsw_sp_port, dev, mlxsw_sp_port->split, 3052 mlxsw_sp_port, dev, module + 1,
2931 module); 3053 mlxsw_sp_port->split, lane / width);
2932 mlxsw_core_schedule_dw(&mlxsw_sp_port->periodic_hw_stats.update_dw, 0); 3054 mlxsw_core_schedule_dw(&mlxsw_sp_port->periodic_hw_stats.update_dw, 0);
2933 return 0; 3055 return 0;
2934 3056
@@ -2937,12 +3059,16 @@ err_register_netdev:
2937 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port); 3059 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
2938 mlxsw_sp_port_vlan_put(mlxsw_sp_port_vlan); 3060 mlxsw_sp_port_vlan_put(mlxsw_sp_port_vlan);
2939err_port_vlan_get: 3061err_port_vlan_get:
3062 mlxsw_sp_port_nve_fini(mlxsw_sp_port);
3063err_port_nve_init:
2940 mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port); 3064 mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
2941err_port_qdiscs_init: 3065err_port_qdiscs_init:
2942 mlxsw_sp_port_fids_fini(mlxsw_sp_port); 3066 mlxsw_sp_port_fids_fini(mlxsw_sp_port);
2943err_port_fids_init: 3067err_port_fids_init:
2944 mlxsw_sp_port_dcb_fini(mlxsw_sp_port); 3068 mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
2945err_port_dcb_init: 3069err_port_dcb_init:
3070 mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
3071err_port_tc_mc_mode:
2946err_port_ets_init: 3072err_port_ets_init:
2947err_port_buffers_init: 3073err_port_buffers_init:
2948err_port_admin_status_set: 3074err_port_admin_status_set:
@@ -2974,9 +3100,11 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
2974 mlxsw_sp->ports[local_port] = NULL; 3100 mlxsw_sp->ports[local_port] = NULL;
2975 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port); 3101 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
2976 mlxsw_sp_port_vlan_flush(mlxsw_sp_port); 3102 mlxsw_sp_port_vlan_flush(mlxsw_sp_port);
3103 mlxsw_sp_port_nve_fini(mlxsw_sp_port);
2977 mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port); 3104 mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
2978 mlxsw_sp_port_fids_fini(mlxsw_sp_port); 3105 mlxsw_sp_port_fids_fini(mlxsw_sp_port);
2979 mlxsw_sp_port_dcb_fini(mlxsw_sp_port); 3106 mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
3107 mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
2980 mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT); 3108 mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
2981 mlxsw_sp_port_module_unmap(mlxsw_sp_port); 3109 mlxsw_sp_port_module_unmap(mlxsw_sp_port);
2982 kfree(mlxsw_sp_port->sample); 3110 kfree(mlxsw_sp_port->sample);
@@ -3103,7 +3231,8 @@ static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp,
3103} 3231}
3104 3232
3105static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, 3233static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
3106 unsigned int count) 3234 unsigned int count,
3235 struct netlink_ext_ack *extack)
3107{ 3236{
3108 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 3237 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3109 struct mlxsw_sp_port *mlxsw_sp_port; 3238 struct mlxsw_sp_port *mlxsw_sp_port;
@@ -3115,6 +3244,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
3115 if (!mlxsw_sp_port) { 3244 if (!mlxsw_sp_port) {
3116 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", 3245 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
3117 local_port); 3246 local_port);
3247 NL_SET_ERR_MSG_MOD(extack, "Port number does not exist");
3118 return -EINVAL; 3248 return -EINVAL;
3119 } 3249 }
3120 3250
@@ -3123,11 +3253,13 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
3123 3253
3124 if (count != 2 && count != 4) { 3254 if (count != 2 && count != 4) {
3125 netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n"); 3255 netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n");
3256 NL_SET_ERR_MSG_MOD(extack, "Port can only be split into 2 or 4 ports");
3126 return -EINVAL; 3257 return -EINVAL;
3127 } 3258 }
3128 3259
3129 if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) { 3260 if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) {
3130 netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n"); 3261 netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
3262 NL_SET_ERR_MSG_MOD(extack, "Port cannot be split further");
3131 return -EINVAL; 3263 return -EINVAL;
3132 } 3264 }
3133 3265
@@ -3136,6 +3268,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
3136 base_port = local_port; 3268 base_port = local_port;
3137 if (mlxsw_sp->ports[base_port + 1]) { 3269 if (mlxsw_sp->ports[base_port + 1]) {
3138 netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n"); 3270 netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
3271 NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration");
3139 return -EINVAL; 3272 return -EINVAL;
3140 } 3273 }
3141 } else { 3274 } else {
@@ -3143,6 +3276,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
3143 if (mlxsw_sp->ports[base_port + 1] || 3276 if (mlxsw_sp->ports[base_port + 1] ||
3144 mlxsw_sp->ports[base_port + 3]) { 3277 mlxsw_sp->ports[base_port + 3]) {
3145 netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n"); 3278 netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
3279 NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration");
3146 return -EINVAL; 3280 return -EINVAL;
3147 } 3281 }
3148 } 3282 }
@@ -3164,7 +3298,8 @@ err_port_split_create:
3164 return err; 3298 return err;
3165} 3299}
3166 3300
3167static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port) 3301static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port,
3302 struct netlink_ext_ack *extack)
3168{ 3303{
3169 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 3304 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3170 struct mlxsw_sp_port *mlxsw_sp_port; 3305 struct mlxsw_sp_port *mlxsw_sp_port;
@@ -3176,11 +3311,13 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port)
3176 if (!mlxsw_sp_port) { 3311 if (!mlxsw_sp_port) {
3177 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", 3312 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
3178 local_port); 3313 local_port);
3314 NL_SET_ERR_MSG_MOD(extack, "Port number does not exist");
3179 return -EINVAL; 3315 return -EINVAL;
3180 } 3316 }
3181 3317
3182 if (!mlxsw_sp_port->split) { 3318 if (!mlxsw_sp_port->split) {
3183 netdev_err(mlxsw_sp_port->dev, "Port wasn't split\n"); 3319 netdev_err(mlxsw_sp_port->dev, "Port was not split\n");
3320 NL_SET_ERR_MSG_MOD(extack, "Port was not split");
3184 return -EINVAL; 3321 return -EINVAL;
3185 } 3322 }
3186 3323
@@ -3373,6 +3510,9 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
3373 MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, TRAP_TO_CPU, ROUTER_EXP, false), 3510 MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, TRAP_TO_CPU, ROUTER_EXP, false),
3374 MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false), 3511 MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false),
3375 MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false), 3512 MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false),
3513 MLXSW_SP_RXL_MARK(DECAP_ECN0, TRAP_TO_CPU, ROUTER_EXP, false),
3514 MLXSW_SP_RXL_MARK(IPV4_VRRP, TRAP_TO_CPU, ROUTER_EXP, false),
3515 MLXSW_SP_RXL_MARK(IPV6_VRRP, TRAP_TO_CPU, ROUTER_EXP, false),
3376 /* PKT Sample trap */ 3516 /* PKT Sample trap */
3377 MLXSW_RXL(mlxsw_sp_rx_listener_sample_func, PKT_SAMPLE, MIRROR_TO_CPU, 3517 MLXSW_RXL(mlxsw_sp_rx_listener_sample_func, PKT_SAMPLE, MIRROR_TO_CPU,
3378 false, SP_IP2ME, DISCARD), 3518 false, SP_IP2ME, DISCARD),
@@ -3384,6 +3524,9 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
3384 MLXSW_SP_RXL_MARK(RPF, TRAP_TO_CPU, RPF, false), 3524 MLXSW_SP_RXL_MARK(RPF, TRAP_TO_CPU, RPF, false),
3385 MLXSW_SP_RXL_MARK(ACL1, TRAP_TO_CPU, MULTICAST, false), 3525 MLXSW_SP_RXL_MARK(ACL1, TRAP_TO_CPU, MULTICAST, false),
3386 MLXSW_SP_RXL_MR_MARK(ACL2, TRAP_TO_CPU, MULTICAST, false), 3526 MLXSW_SP_RXL_MR_MARK(ACL2, TRAP_TO_CPU, MULTICAST, false),
3527 /* NVE traps */
3528 MLXSW_SP_RXL_MARK(NVE_ENCAP_ARP, TRAP_TO_CPU, ARP, false),
3529 MLXSW_SP_RXL_NO_MARK(NVE_DECAP_ARP, TRAP_TO_CPU, ARP, false),
3387}; 3530};
3388 3531
3389static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core) 3532static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
@@ -3431,7 +3574,6 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
3431 burst_size = 7; 3574 burst_size = 7;
3432 break; 3575 break;
3433 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME: 3576 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME:
3434 is_bytes = true;
3435 rate = 4 * 1024; 3577 rate = 4 * 1024;
3436 burst_size = 4; 3578 burst_size = 4;
3437 break; 3579 break;
@@ -3568,8 +3710,10 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
3568static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp) 3710static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
3569{ 3711{
3570 char slcr_pl[MLXSW_REG_SLCR_LEN]; 3712 char slcr_pl[MLXSW_REG_SLCR_LEN];
3713 u32 seed;
3571 int err; 3714 int err;
3572 3715
3716 get_random_bytes(&seed, sizeof(seed));
3573 mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC | 3717 mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
3574 MLXSW_REG_SLCR_LAG_HASH_DMAC | 3718 MLXSW_REG_SLCR_LAG_HASH_DMAC |
3575 MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE | 3719 MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
@@ -3578,7 +3722,7 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
3578 MLXSW_REG_SLCR_LAG_HASH_DIP | 3722 MLXSW_REG_SLCR_LAG_HASH_DIP |
3579 MLXSW_REG_SLCR_LAG_HASH_SPORT | 3723 MLXSW_REG_SLCR_LAG_HASH_SPORT |
3580 MLXSW_REG_SLCR_LAG_HASH_DPORT | 3724 MLXSW_REG_SLCR_LAG_HASH_DPORT |
3581 MLXSW_REG_SLCR_LAG_HASH_IPPROTO); 3725 MLXSW_REG_SLCR_LAG_HASH_IPPROTO, seed);
3582 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcr), slcr_pl); 3726 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcr), slcr_pl);
3583 if (err) 3727 if (err)
3584 return err; 3728 return err;
@@ -3625,10 +3769,8 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
3625 mlxsw_sp->bus_info = mlxsw_bus_info; 3769 mlxsw_sp->bus_info = mlxsw_bus_info;
3626 3770
3627 err = mlxsw_sp_fw_rev_validate(mlxsw_sp); 3771 err = mlxsw_sp_fw_rev_validate(mlxsw_sp);
3628 if (err) { 3772 if (err)
3629 dev_err(mlxsw_sp->bus_info->dev, "Could not upgrade firmware\n");
3630 return err; 3773 return err;
3631 }
3632 3774
3633 err = mlxsw_sp_base_mac_get(mlxsw_sp); 3775 err = mlxsw_sp_base_mac_get(mlxsw_sp);
3634 if (err) { 3776 if (err) {
@@ -3666,6 +3808,15 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
3666 goto err_lag_init; 3808 goto err_lag_init;
3667 } 3809 }
3668 3810
3811 /* Initialize SPAN before router and switchdev, so that those components
3812 * can call mlxsw_sp_span_respin().
3813 */
3814 err = mlxsw_sp_span_init(mlxsw_sp);
3815 if (err) {
3816 dev_err(mlxsw_sp->bus_info->dev, "Failed to init span system\n");
3817 goto err_span_init;
3818 }
3819
3669 err = mlxsw_sp_switchdev_init(mlxsw_sp); 3820 err = mlxsw_sp_switchdev_init(mlxsw_sp);
3670 if (err) { 3821 if (err) {
3671 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize switchdev\n"); 3822 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize switchdev\n");
@@ -3684,15 +3835,12 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
3684 goto err_afa_init; 3835 goto err_afa_init;
3685 } 3836 }
3686 3837
3687 err = mlxsw_sp_span_init(mlxsw_sp); 3838 err = mlxsw_sp_nve_init(mlxsw_sp);
3688 if (err) { 3839 if (err) {
3689 dev_err(mlxsw_sp->bus_info->dev, "Failed to init span system\n"); 3840 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize NVE\n");
3690 goto err_span_init; 3841 goto err_nve_init;
3691 } 3842 }
3692 3843
3693 /* Initialize router after SPAN is initialized, so that the FIB and
3694 * neighbor event handlers can issue SPAN respin.
3695 */
3696 err = mlxsw_sp_router_init(mlxsw_sp); 3844 err = mlxsw_sp_router_init(mlxsw_sp);
3697 if (err) { 3845 if (err) {
3698 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n"); 3846 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n");
@@ -3739,14 +3887,16 @@ err_acl_init:
3739err_netdev_notifier: 3887err_netdev_notifier:
3740 mlxsw_sp_router_fini(mlxsw_sp); 3888 mlxsw_sp_router_fini(mlxsw_sp);
3741err_router_init: 3889err_router_init:
3742 mlxsw_sp_span_fini(mlxsw_sp); 3890 mlxsw_sp_nve_fini(mlxsw_sp);
3743err_span_init: 3891err_nve_init:
3744 mlxsw_sp_afa_fini(mlxsw_sp); 3892 mlxsw_sp_afa_fini(mlxsw_sp);
3745err_afa_init: 3893err_afa_init:
3746 mlxsw_sp_counter_pool_fini(mlxsw_sp); 3894 mlxsw_sp_counter_pool_fini(mlxsw_sp);
3747err_counter_pool_init: 3895err_counter_pool_init:
3748 mlxsw_sp_switchdev_fini(mlxsw_sp); 3896 mlxsw_sp_switchdev_fini(mlxsw_sp);
3749err_switchdev_init: 3897err_switchdev_init:
3898 mlxsw_sp_span_fini(mlxsw_sp);
3899err_span_init:
3750 mlxsw_sp_lag_fini(mlxsw_sp); 3900 mlxsw_sp_lag_fini(mlxsw_sp);
3751err_lag_init: 3901err_lag_init:
3752 mlxsw_sp_buffers_fini(mlxsw_sp); 3902 mlxsw_sp_buffers_fini(mlxsw_sp);
@@ -3759,6 +3909,38 @@ err_fids_init:
3759 return err; 3909 return err;
3760} 3910}
3761 3911
3912static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core,
3913 const struct mlxsw_bus_info *mlxsw_bus_info)
3914{
3915 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3916
3917 mlxsw_sp->req_rev = &mlxsw_sp1_fw_rev;
3918 mlxsw_sp->fw_filename = MLXSW_SP1_FW_FILENAME;
3919 mlxsw_sp->kvdl_ops = &mlxsw_sp1_kvdl_ops;
3920 mlxsw_sp->afa_ops = &mlxsw_sp1_act_afa_ops;
3921 mlxsw_sp->afk_ops = &mlxsw_sp1_afk_ops;
3922 mlxsw_sp->mr_tcam_ops = &mlxsw_sp1_mr_tcam_ops;
3923 mlxsw_sp->acl_tcam_ops = &mlxsw_sp1_acl_tcam_ops;
3924 mlxsw_sp->nve_ops_arr = mlxsw_sp1_nve_ops_arr;
3925
3926 return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info);
3927}
3928
3929static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
3930 const struct mlxsw_bus_info *mlxsw_bus_info)
3931{
3932 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3933
3934 mlxsw_sp->kvdl_ops = &mlxsw_sp2_kvdl_ops;
3935 mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
3936 mlxsw_sp->afk_ops = &mlxsw_sp2_afk_ops;
3937 mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
3938 mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
3939 mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
3940
3941 return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info);
3942}
3943
3762static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core) 3944static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
3763{ 3945{
3764 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 3946 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
@@ -3768,10 +3950,11 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
3768 mlxsw_sp_acl_fini(mlxsw_sp); 3950 mlxsw_sp_acl_fini(mlxsw_sp);
3769 unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb); 3951 unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb);
3770 mlxsw_sp_router_fini(mlxsw_sp); 3952 mlxsw_sp_router_fini(mlxsw_sp);
3771 mlxsw_sp_span_fini(mlxsw_sp); 3953 mlxsw_sp_nve_fini(mlxsw_sp);
3772 mlxsw_sp_afa_fini(mlxsw_sp); 3954 mlxsw_sp_afa_fini(mlxsw_sp);
3773 mlxsw_sp_counter_pool_fini(mlxsw_sp); 3955 mlxsw_sp_counter_pool_fini(mlxsw_sp);
3774 mlxsw_sp_switchdev_fini(mlxsw_sp); 3956 mlxsw_sp_switchdev_fini(mlxsw_sp);
3957 mlxsw_sp_span_fini(mlxsw_sp);
3775 mlxsw_sp_lag_fini(mlxsw_sp); 3958 mlxsw_sp_lag_fini(mlxsw_sp);
3776 mlxsw_sp_buffers_fini(mlxsw_sp); 3959 mlxsw_sp_buffers_fini(mlxsw_sp);
3777 mlxsw_sp_traps_fini(mlxsw_sp); 3960 mlxsw_sp_traps_fini(mlxsw_sp);
@@ -3779,7 +3962,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
3779 mlxsw_sp_kvdl_fini(mlxsw_sp); 3962 mlxsw_sp_kvdl_fini(mlxsw_sp);
3780} 3963}
3781 3964
3782static const struct mlxsw_config_profile mlxsw_sp_config_profile = { 3965static const struct mlxsw_config_profile mlxsw_sp1_config_profile = {
3783 .used_max_mid = 1, 3966 .used_max_mid = 1,
3784 .max_mid = MLXSW_SP_MID_MAX, 3967 .max_mid = MLXSW_SP_MID_MAX,
3785 .used_flood_tables = 1, 3968 .used_flood_tables = 1,
@@ -3805,6 +3988,28 @@ static const struct mlxsw_config_profile mlxsw_sp_config_profile = {
3805 }, 3988 },
3806}; 3989};
3807 3990
3991static const struct mlxsw_config_profile mlxsw_sp2_config_profile = {
3992 .used_max_mid = 1,
3993 .max_mid = MLXSW_SP_MID_MAX,
3994 .used_flood_tables = 1,
3995 .used_flood_mode = 1,
3996 .flood_mode = 3,
3997 .max_fid_offset_flood_tables = 3,
3998 .fid_offset_flood_table_size = VLAN_N_VID - 1,
3999 .max_fid_flood_tables = 3,
4000 .fid_flood_table_size = MLXSW_SP_FID_8021D_MAX,
4001 .used_max_ib_mc = 1,
4002 .max_ib_mc = 0,
4003 .used_max_pkey = 1,
4004 .max_pkey = 0,
4005 .swid_config = {
4006 {
4007 .used_type = 1,
4008 .type = MLXSW_PORT_SWID_TYPE_ETH,
4009 }
4010 },
4011};
4012
3808static void 4013static void
3809mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core, 4014mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core,
3810 struct devlink_resource_size_params *kvd_size_params, 4015 struct devlink_resource_size_params *kvd_size_params,
@@ -3841,7 +4046,7 @@ mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core,
3841 DEVLINK_RESOURCE_UNIT_ENTRY); 4046 DEVLINK_RESOURCE_UNIT_ENTRY);
3842} 4047}
3843 4048
3844static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core) 4049static int mlxsw_sp1_resources_kvd_register(struct mlxsw_core *mlxsw_core)
3845{ 4050{
3846 struct devlink *devlink = priv_to_devlink(mlxsw_core); 4051 struct devlink *devlink = priv_to_devlink(mlxsw_core);
3847 struct devlink_resource_size_params hash_single_size_params; 4052 struct devlink_resource_size_params hash_single_size_params;
@@ -3852,7 +4057,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
3852 const struct mlxsw_config_profile *profile; 4057 const struct mlxsw_config_profile *profile;
3853 int err; 4058 int err;
3854 4059
3855 profile = &mlxsw_sp_config_profile; 4060 profile = &mlxsw_sp1_config_profile;
3856 if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SIZE)) 4061 if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SIZE))
3857 return -EIO; 4062 return -EIO;
3858 4063
@@ -3878,7 +4083,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
3878 if (err) 4083 if (err)
3879 return err; 4084 return err;
3880 4085
3881 err = mlxsw_sp_kvdl_resources_register(mlxsw_core); 4086 err = mlxsw_sp1_kvdl_resources_register(mlxsw_core);
3882 if (err) 4087 if (err)
3883 return err; 4088 return err;
3884 4089
@@ -3907,6 +4112,16 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
3907 return 0; 4112 return 0;
3908} 4113}
3909 4114
4115static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
4116{
4117 return mlxsw_sp1_resources_kvd_register(mlxsw_core);
4118}
4119
4120static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
4121{
4122 return 0;
4123}
4124
3910static int mlxsw_sp_kvd_sizes_get(struct mlxsw_core *mlxsw_core, 4125static int mlxsw_sp_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
3911 const struct mlxsw_config_profile *profile, 4126 const struct mlxsw_config_profile *profile,
3912 u64 *p_single_size, u64 *p_double_size, 4127 u64 *p_single_size, u64 *p_double_size,
@@ -3962,10 +4177,10 @@ static int mlxsw_sp_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
3962 return 0; 4177 return 0;
3963} 4178}
3964 4179
3965static struct mlxsw_driver mlxsw_sp_driver = { 4180static struct mlxsw_driver mlxsw_sp1_driver = {
3966 .kind = mlxsw_sp_driver_name, 4181 .kind = mlxsw_sp1_driver_name,
3967 .priv_size = sizeof(struct mlxsw_sp), 4182 .priv_size = sizeof(struct mlxsw_sp),
3968 .init = mlxsw_sp_init, 4183 .init = mlxsw_sp1_init,
3969 .fini = mlxsw_sp_fini, 4184 .fini = mlxsw_sp_fini,
3970 .basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set, 4185 .basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set,
3971 .port_split = mlxsw_sp_port_split, 4186 .port_split = mlxsw_sp_port_split,
@@ -3981,10 +4196,35 @@ static struct mlxsw_driver mlxsw_sp_driver = {
3981 .sb_occ_port_pool_get = mlxsw_sp_sb_occ_port_pool_get, 4196 .sb_occ_port_pool_get = mlxsw_sp_sb_occ_port_pool_get,
3982 .sb_occ_tc_port_bind_get = mlxsw_sp_sb_occ_tc_port_bind_get, 4197 .sb_occ_tc_port_bind_get = mlxsw_sp_sb_occ_tc_port_bind_get,
3983 .txhdr_construct = mlxsw_sp_txhdr_construct, 4198 .txhdr_construct = mlxsw_sp_txhdr_construct,
3984 .resources_register = mlxsw_sp_resources_register, 4199 .resources_register = mlxsw_sp1_resources_register,
3985 .kvd_sizes_get = mlxsw_sp_kvd_sizes_get, 4200 .kvd_sizes_get = mlxsw_sp_kvd_sizes_get,
3986 .txhdr_len = MLXSW_TXHDR_LEN, 4201 .txhdr_len = MLXSW_TXHDR_LEN,
3987 .profile = &mlxsw_sp_config_profile, 4202 .profile = &mlxsw_sp1_config_profile,
4203 .res_query_enabled = true,
4204};
4205
4206static struct mlxsw_driver mlxsw_sp2_driver = {
4207 .kind = mlxsw_sp2_driver_name,
4208 .priv_size = sizeof(struct mlxsw_sp),
4209 .init = mlxsw_sp2_init,
4210 .fini = mlxsw_sp_fini,
4211 .basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set,
4212 .port_split = mlxsw_sp_port_split,
4213 .port_unsplit = mlxsw_sp_port_unsplit,
4214 .sb_pool_get = mlxsw_sp_sb_pool_get,
4215 .sb_pool_set = mlxsw_sp_sb_pool_set,
4216 .sb_port_pool_get = mlxsw_sp_sb_port_pool_get,
4217 .sb_port_pool_set = mlxsw_sp_sb_port_pool_set,
4218 .sb_tc_pool_bind_get = mlxsw_sp_sb_tc_pool_bind_get,
4219 .sb_tc_pool_bind_set = mlxsw_sp_sb_tc_pool_bind_set,
4220 .sb_occ_snapshot = mlxsw_sp_sb_occ_snapshot,
4221 .sb_occ_max_clear = mlxsw_sp_sb_occ_max_clear,
4222 .sb_occ_port_pool_get = mlxsw_sp_sb_occ_port_pool_get,
4223 .sb_occ_tc_port_bind_get = mlxsw_sp_sb_occ_tc_port_bind_get,
4224 .txhdr_construct = mlxsw_sp_txhdr_construct,
4225 .resources_register = mlxsw_sp2_resources_register,
4226 .txhdr_len = MLXSW_TXHDR_LEN,
4227 .profile = &mlxsw_sp2_config_profile,
3988 .res_query_enabled = true, 4228 .res_query_enabled = true,
3989}; 4229};
3990 4230
@@ -4377,6 +4617,41 @@ static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port)
4377 mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false); 4617 mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
4378} 4618}
4379 4619
4620static bool mlxsw_sp_bridge_has_multiple_vxlans(struct net_device *br_dev)
4621{
4622 unsigned int num_vxlans = 0;
4623 struct net_device *dev;
4624 struct list_head *iter;
4625
4626 netdev_for_each_lower_dev(br_dev, dev, iter) {
4627 if (netif_is_vxlan(dev))
4628 num_vxlans++;
4629 }
4630
4631 return num_vxlans > 1;
4632}
4633
4634static bool mlxsw_sp_bridge_vxlan_is_valid(struct net_device *br_dev,
4635 struct netlink_ext_ack *extack)
4636{
4637 if (br_multicast_enabled(br_dev)) {
4638 NL_SET_ERR_MSG_MOD(extack, "Multicast can not be enabled on a bridge with a VxLAN device");
4639 return false;
4640 }
4641
4642 if (br_vlan_enabled(br_dev)) {
4643 NL_SET_ERR_MSG_MOD(extack, "VLAN filtering can not be enabled on a bridge with a VxLAN device");
4644 return false;
4645 }
4646
4647 if (mlxsw_sp_bridge_has_multiple_vxlans(br_dev)) {
4648 NL_SET_ERR_MSG_MOD(extack, "Multiple VxLAN devices are not supported in a VLAN-unaware bridge");
4649 return false;
4650 }
4651
4652 return true;
4653}
4654
4380static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev, 4655static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
4381 struct net_device *dev, 4656 struct net_device *dev,
4382 unsigned long event, void *ptr) 4657 unsigned long event, void *ptr)
@@ -4399,12 +4674,18 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
4399 if (!is_vlan_dev(upper_dev) && 4674 if (!is_vlan_dev(upper_dev) &&
4400 !netif_is_lag_master(upper_dev) && 4675 !netif_is_lag_master(upper_dev) &&
4401 !netif_is_bridge_master(upper_dev) && 4676 !netif_is_bridge_master(upper_dev) &&
4402 !netif_is_ovs_master(upper_dev)) { 4677 !netif_is_ovs_master(upper_dev) &&
4678 !netif_is_macvlan(upper_dev)) {
4403 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type"); 4679 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4404 return -EINVAL; 4680 return -EINVAL;
4405 } 4681 }
4406 if (!info->linking) 4682 if (!info->linking)
4407 break; 4683 break;
4684 if (netif_is_bridge_master(upper_dev) &&
4685 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, upper_dev) &&
4686 mlxsw_sp_bridge_has_vxlan(upper_dev) &&
4687 !mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
4688 return -EOPNOTSUPP;
4408 if (netdev_has_any_upper_dev(upper_dev) && 4689 if (netdev_has_any_upper_dev(upper_dev) &&
4409 (!netif_is_bridge_master(upper_dev) || 4690 (!netif_is_bridge_master(upper_dev) ||
4410 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, 4691 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
@@ -4425,6 +4706,11 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
4425 NL_SET_ERR_MSG_MOD(extack, "Can not put a VLAN on a LAG port"); 4706 NL_SET_ERR_MSG_MOD(extack, "Can not put a VLAN on a LAG port");
4426 return -EINVAL; 4707 return -EINVAL;
4427 } 4708 }
4709 if (netif_is_macvlan(upper_dev) &&
4710 !mlxsw_sp_rif_find_by_dev(mlxsw_sp, lower_dev)) {
4711 NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
4712 return -EOPNOTSUPP;
4713 }
4428 if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) { 4714 if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) {
4429 NL_SET_ERR_MSG_MOD(extack, "Master device is an OVS master and this device has a VLAN"); 4715 NL_SET_ERR_MSG_MOD(extack, "Master device is an OVS master and this device has a VLAN");
4430 return -EINVAL; 4716 return -EINVAL;
@@ -4463,6 +4749,9 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
4463 err = mlxsw_sp_port_ovs_join(mlxsw_sp_port); 4749 err = mlxsw_sp_port_ovs_join(mlxsw_sp_port);
4464 else 4750 else
4465 mlxsw_sp_port_ovs_leave(mlxsw_sp_port); 4751 mlxsw_sp_port_ovs_leave(mlxsw_sp_port);
4752 } else if (netif_is_macvlan(upper_dev)) {
4753 if (!info->linking)
4754 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
4466 } 4755 }
4467 break; 4756 break;
4468 } 4757 }
@@ -4547,12 +4836,18 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
4547 switch (event) { 4836 switch (event) {
4548 case NETDEV_PRECHANGEUPPER: 4837 case NETDEV_PRECHANGEUPPER:
4549 upper_dev = info->upper_dev; 4838 upper_dev = info->upper_dev;
4550 if (!netif_is_bridge_master(upper_dev)) { 4839 if (!netif_is_bridge_master(upper_dev) &&
4551 NL_SET_ERR_MSG_MOD(extack, "VLAN devices only support bridge and VRF uppers"); 4840 !netif_is_macvlan(upper_dev)) {
4841 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4552 return -EINVAL; 4842 return -EINVAL;
4553 } 4843 }
4554 if (!info->linking) 4844 if (!info->linking)
4555 break; 4845 break;
4846 if (netif_is_bridge_master(upper_dev) &&
4847 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, upper_dev) &&
4848 mlxsw_sp_bridge_has_vxlan(upper_dev) &&
4849 !mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
4850 return -EOPNOTSUPP;
4556 if (netdev_has_any_upper_dev(upper_dev) && 4851 if (netdev_has_any_upper_dev(upper_dev) &&
4557 (!netif_is_bridge_master(upper_dev) || 4852 (!netif_is_bridge_master(upper_dev) ||
4558 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, 4853 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
@@ -4560,6 +4855,11 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
4560 NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a device that already has an upper device is not supported"); 4855 NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a device that already has an upper device is not supported");
4561 return -EINVAL; 4856 return -EINVAL;
4562 } 4857 }
4858 if (netif_is_macvlan(upper_dev) &&
4859 !mlxsw_sp_rif_find_by_dev(mlxsw_sp, vlan_dev)) {
4860 NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
4861 return -EOPNOTSUPP;
4862 }
4563 break; 4863 break;
4564 case NETDEV_CHANGEUPPER: 4864 case NETDEV_CHANGEUPPER:
4565 upper_dev = info->upper_dev; 4865 upper_dev = info->upper_dev;
@@ -4573,6 +4873,9 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
4573 mlxsw_sp_port_bridge_leave(mlxsw_sp_port, 4873 mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
4574 vlan_dev, 4874 vlan_dev,
4575 upper_dev); 4875 upper_dev);
4876 } else if (netif_is_macvlan(upper_dev)) {
4877 if (!info->linking)
4878 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
4576 } else { 4879 } else {
4577 err = -EINVAL; 4880 err = -EINVAL;
4578 WARN_ON(1); 4881 WARN_ON(1);
@@ -4622,6 +4925,66 @@ static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
4622 return 0; 4925 return 0;
4623} 4926}
4624 4927
4928static int mlxsw_sp_netdevice_bridge_event(struct net_device *br_dev,
4929 unsigned long event, void *ptr)
4930{
4931 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(br_dev);
4932 struct netdev_notifier_changeupper_info *info = ptr;
4933 struct netlink_ext_ack *extack;
4934 struct net_device *upper_dev;
4935
4936 if (!mlxsw_sp)
4937 return 0;
4938
4939 extack = netdev_notifier_info_to_extack(&info->info);
4940
4941 switch (event) {
4942 case NETDEV_PRECHANGEUPPER:
4943 upper_dev = info->upper_dev;
4944 if (!is_vlan_dev(upper_dev) && !netif_is_macvlan(upper_dev)) {
4945 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4946 return -EOPNOTSUPP;
4947 }
4948 if (!info->linking)
4949 break;
4950 if (netif_is_macvlan(upper_dev) &&
4951 !mlxsw_sp_rif_find_by_dev(mlxsw_sp, br_dev)) {
4952 NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
4953 return -EOPNOTSUPP;
4954 }
4955 break;
4956 case NETDEV_CHANGEUPPER:
4957 upper_dev = info->upper_dev;
4958 if (info->linking)
4959 break;
4960 if (is_vlan_dev(upper_dev))
4961 mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, upper_dev);
4962 if (netif_is_macvlan(upper_dev))
4963 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
4964 break;
4965 }
4966
4967 return 0;
4968}
4969
4970static int mlxsw_sp_netdevice_macvlan_event(struct net_device *macvlan_dev,
4971 unsigned long event, void *ptr)
4972{
4973 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(macvlan_dev);
4974 struct netdev_notifier_changeupper_info *info = ptr;
4975 struct netlink_ext_ack *extack;
4976
4977 if (!mlxsw_sp || event != NETDEV_PRECHANGEUPPER)
4978 return 0;
4979
4980 extack = netdev_notifier_info_to_extack(&info->info);
4981
4982 /* VRF enslavement is handled in mlxsw_sp_netdevice_vrf_event() */
4983 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4984
4985 return -EOPNOTSUPP;
4986}
4987
4625static bool mlxsw_sp_is_vrf_event(unsigned long event, void *ptr) 4988static bool mlxsw_sp_is_vrf_event(unsigned long event, void *ptr)
4626{ 4989{
4627 struct netdev_notifier_changeupper_info *info = ptr; 4990 struct netdev_notifier_changeupper_info *info = ptr;
@@ -4631,6 +4994,63 @@ static bool mlxsw_sp_is_vrf_event(unsigned long event, void *ptr)
4631 return netif_is_l3_master(info->upper_dev); 4994 return netif_is_l3_master(info->upper_dev);
4632} 4995}
4633 4996
4997static int mlxsw_sp_netdevice_vxlan_event(struct mlxsw_sp *mlxsw_sp,
4998 struct net_device *dev,
4999 unsigned long event, void *ptr)
5000{
5001 struct netdev_notifier_changeupper_info *cu_info;
5002 struct netdev_notifier_info *info = ptr;
5003 struct netlink_ext_ack *extack;
5004 struct net_device *upper_dev;
5005
5006 extack = netdev_notifier_info_to_extack(info);
5007
5008 switch (event) {
5009 case NETDEV_CHANGEUPPER:
5010 cu_info = container_of(info,
5011 struct netdev_notifier_changeupper_info,
5012 info);
5013 upper_dev = cu_info->upper_dev;
5014 if (!netif_is_bridge_master(upper_dev))
5015 return 0;
5016 if (!mlxsw_sp_lower_get(upper_dev))
5017 return 0;
5018 if (!mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
5019 return -EOPNOTSUPP;
5020 if (cu_info->linking) {
5021 if (!netif_running(dev))
5022 return 0;
5023 return mlxsw_sp_bridge_vxlan_join(mlxsw_sp, upper_dev,
5024 dev, extack);
5025 } else {
5026 mlxsw_sp_bridge_vxlan_leave(mlxsw_sp, upper_dev, dev);
5027 }
5028 break;
5029 case NETDEV_PRE_UP:
5030 upper_dev = netdev_master_upper_dev_get(dev);
5031 if (!upper_dev)
5032 return 0;
5033 if (!netif_is_bridge_master(upper_dev))
5034 return 0;
5035 if (!mlxsw_sp_lower_get(upper_dev))
5036 return 0;
5037 return mlxsw_sp_bridge_vxlan_join(mlxsw_sp, upper_dev, dev,
5038 extack);
5039 case NETDEV_DOWN:
5040 upper_dev = netdev_master_upper_dev_get(dev);
5041 if (!upper_dev)
5042 return 0;
5043 if (!netif_is_bridge_master(upper_dev))
5044 return 0;
5045 if (!mlxsw_sp_lower_get(upper_dev))
5046 return 0;
5047 mlxsw_sp_bridge_vxlan_leave(mlxsw_sp, upper_dev, dev);
5048 break;
5049 }
5050
5051 return 0;
5052}
5053
4634static int mlxsw_sp_netdevice_event(struct notifier_block *nb, 5054static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
4635 unsigned long event, void *ptr) 5055 unsigned long event, void *ptr)
4636{ 5056{
@@ -4647,6 +5067,8 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
4647 } 5067 }
4648 mlxsw_sp_span_respin(mlxsw_sp); 5068 mlxsw_sp_span_respin(mlxsw_sp);
4649 5069
5070 if (netif_is_vxlan(dev))
5071 err = mlxsw_sp_netdevice_vxlan_event(mlxsw_sp, dev, event, ptr);
4650 if (mlxsw_sp_netdev_is_ipip_ol(mlxsw_sp, dev)) 5072 if (mlxsw_sp_netdev_is_ipip_ol(mlxsw_sp, dev))
4651 err = mlxsw_sp_netdevice_ipip_ol_event(mlxsw_sp, dev, 5073 err = mlxsw_sp_netdevice_ipip_ol_event(mlxsw_sp, dev,
4652 event, ptr); 5074 event, ptr);
@@ -4663,6 +5085,10 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
4663 err = mlxsw_sp_netdevice_lag_event(dev, event, ptr); 5085 err = mlxsw_sp_netdevice_lag_event(dev, event, ptr);
4664 else if (is_vlan_dev(dev)) 5086 else if (is_vlan_dev(dev))
4665 err = mlxsw_sp_netdevice_vlan_event(dev, event, ptr); 5087 err = mlxsw_sp_netdevice_vlan_event(dev, event, ptr);
5088 else if (netif_is_bridge_master(dev))
5089 err = mlxsw_sp_netdevice_bridge_event(dev, event, ptr);
5090 else if (netif_is_macvlan(dev))
5091 err = mlxsw_sp_netdevice_macvlan_event(dev, event, ptr);
4666 5092
4667 return notifier_from_errno(err); 5093 return notifier_from_errno(err);
4668} 5094}
@@ -4683,14 +5109,24 @@ static struct notifier_block mlxsw_sp_inet6addr_nb __read_mostly = {
4683 .notifier_call = mlxsw_sp_inet6addr_event, 5109 .notifier_call = mlxsw_sp_inet6addr_event,
4684}; 5110};
4685 5111
4686static const struct pci_device_id mlxsw_sp_pci_id_table[] = { 5112static const struct pci_device_id mlxsw_sp1_pci_id_table[] = {
4687 {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0}, 5113 {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0},
4688 {0, }, 5114 {0, },
4689}; 5115};
4690 5116
4691static struct pci_driver mlxsw_sp_pci_driver = { 5117static struct pci_driver mlxsw_sp1_pci_driver = {
4692 .name = mlxsw_sp_driver_name, 5118 .name = mlxsw_sp1_driver_name,
4693 .id_table = mlxsw_sp_pci_id_table, 5119 .id_table = mlxsw_sp1_pci_id_table,
5120};
5121
5122static const struct pci_device_id mlxsw_sp2_pci_id_table[] = {
5123 {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM2), 0},
5124 {0, },
5125};
5126
5127static struct pci_driver mlxsw_sp2_pci_driver = {
5128 .name = mlxsw_sp2_driver_name,
5129 .id_table = mlxsw_sp2_pci_id_table,
4694}; 5130};
4695 5131
4696static int __init mlxsw_sp_module_init(void) 5132static int __init mlxsw_sp_module_init(void)
@@ -4702,19 +5138,31 @@ static int __init mlxsw_sp_module_init(void)
4702 register_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb); 5138 register_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
4703 register_inet6addr_notifier(&mlxsw_sp_inet6addr_nb); 5139 register_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
4704 5140
4705 err = mlxsw_core_driver_register(&mlxsw_sp_driver); 5141 err = mlxsw_core_driver_register(&mlxsw_sp1_driver);
5142 if (err)
5143 goto err_sp1_core_driver_register;
5144
5145 err = mlxsw_core_driver_register(&mlxsw_sp2_driver);
5146 if (err)
5147 goto err_sp2_core_driver_register;
5148
5149 err = mlxsw_pci_driver_register(&mlxsw_sp1_pci_driver);
4706 if (err) 5150 if (err)
4707 goto err_core_driver_register; 5151 goto err_sp1_pci_driver_register;
4708 5152
4709 err = mlxsw_pci_driver_register(&mlxsw_sp_pci_driver); 5153 err = mlxsw_pci_driver_register(&mlxsw_sp2_pci_driver);
4710 if (err) 5154 if (err)
4711 goto err_pci_driver_register; 5155 goto err_sp2_pci_driver_register;
4712 5156
4713 return 0; 5157 return 0;
4714 5158
4715err_pci_driver_register: 5159err_sp2_pci_driver_register:
4716 mlxsw_core_driver_unregister(&mlxsw_sp_driver); 5160 mlxsw_pci_driver_unregister(&mlxsw_sp2_pci_driver);
4717err_core_driver_register: 5161err_sp1_pci_driver_register:
5162 mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
5163err_sp2_core_driver_register:
5164 mlxsw_core_driver_unregister(&mlxsw_sp1_driver);
5165err_sp1_core_driver_register:
4718 unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb); 5166 unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
4719 unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb); 5167 unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
4720 unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb); 5168 unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
@@ -4724,8 +5172,10 @@ err_core_driver_register:
4724 5172
4725static void __exit mlxsw_sp_module_exit(void) 5173static void __exit mlxsw_sp_module_exit(void)
4726{ 5174{
4727 mlxsw_pci_driver_unregister(&mlxsw_sp_pci_driver); 5175 mlxsw_pci_driver_unregister(&mlxsw_sp2_pci_driver);
4728 mlxsw_core_driver_unregister(&mlxsw_sp_driver); 5176 mlxsw_pci_driver_unregister(&mlxsw_sp1_pci_driver);
5177 mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
5178 mlxsw_core_driver_unregister(&mlxsw_sp1_driver);
4729 unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb); 5179 unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
4730 unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb); 5180 unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
4731 unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb); 5181 unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
@@ -4738,5 +5188,6 @@ module_exit(mlxsw_sp_module_exit);
4738MODULE_LICENSE("Dual BSD/GPL"); 5188MODULE_LICENSE("Dual BSD/GPL");
4739MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>"); 5189MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
4740MODULE_DESCRIPTION("Mellanox Spectrum driver"); 5190MODULE_DESCRIPTION("Mellanox Spectrum driver");
4741MODULE_DEVICE_TABLE(pci, mlxsw_sp_pci_id_table); 5191MODULE_DEVICE_TABLE(pci, mlxsw_sp1_pci_id_table);
4742MODULE_FIRMWARE(MLXSW_SP_FW_FILENAME); 5192MODULE_DEVICE_TABLE(pci, mlxsw_sp2_pci_id_table);
5193MODULE_FIRMWARE(MLXSW_SP1_FW_FILENAME);