mlxsw: spectrum: Keep maximum MTU around
authorPetr Machata <petrm@nvidia.com>
Sun, 13 Sep 2020 15:46:07 +0000 (18:46 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 14 Sep 2020 21:37:30 +0000 (14:37 -0700)
The maximum port MTU depends on port type. On Spectrum, mlxsw configures
all ports as Ethernet ports, and the maximum MTU therefore never changes.
Besides checking MTU configuration, maximum MTU will also be handy when
setting SBIB, the internal buffer used for traffic mirroring. Therefore,
keep it in struct mlxsw_sp_port for easy access.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h

index 4186e29119c27d134ee867ddb86cca418f2d7d95..a68e62256bee9213c105302c4b40a9b87028b993 100644 (file)
@@ -590,21 +590,28 @@ static int mlxsw_sp_port_dev_addr_init(struct mlxsw_sp_port *mlxsw_sp_port)
        return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr);
 }
 
-static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
+static int mlxsw_sp_port_max_mtu_get(struct mlxsw_sp_port *mlxsw_sp_port, int *p_max_mtu)
 {
        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
        char pmtu_pl[MLXSW_REG_PMTU_LEN];
-       int max_mtu;
        int err;
 
-       mtu += MLXSW_TXHDR_LEN + ETH_HLEN;
        mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, 0);
        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
        if (err)
                return err;
-       max_mtu = mlxsw_reg_pmtu_max_mtu_get(pmtu_pl);
 
-       if (mtu > max_mtu)
+       *p_max_mtu = mlxsw_reg_pmtu_max_mtu_get(pmtu_pl);
+       return 0;
+}
+
+static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
+{
+       struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+       char pmtu_pl[MLXSW_REG_PMTU_LEN];
+
+       mtu += MLXSW_TXHDR_LEN + ETH_HLEN;
+       if (mtu > mlxsw_sp_port->max_mtu)
                return -EINVAL;
 
        mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, mtu);
@@ -1842,6 +1849,13 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
                goto err_port_speed_by_width_set;
        }
 
+       err = mlxsw_sp_port_max_mtu_get(mlxsw_sp_port, &mlxsw_sp_port->max_mtu);
+       if (err) {
+               dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to get maximum MTU\n",
+                       mlxsw_sp_port->local_port);
+               goto err_port_max_mtu_get;
+       }
+
        err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, ETH_DATA_LEN);
        if (err) {
                dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set MTU\n",
@@ -1966,6 +1980,7 @@ err_port_ets_init:
 err_port_buffers_init:
 err_port_admin_status_set:
 err_port_mtu_set:
+err_port_max_mtu_get:
 err_port_speed_by_width_set:
 err_port_system_port_mapping_set:
 err_dev_addr_init:
index 007e97e99ec8ff4dc79521904e2881347bee2df4..69e59cf7812f7f5821a5e797af2fe3980566ecd4 100644 (file)
@@ -319,6 +319,7 @@ struct mlxsw_sp_port {
        struct {
                struct delayed_work speed_update_dw;
        } span;
+       int max_mtu;
 };
 
 struct mlxsw_sp_port_type_speed_ops {