Commit 7b819530 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

mlxsw: spectrum: Configure MC-aware mode on mlxsw ports

In order to give unicast traffic precedence over BUM traffic, configure
multicast-aware mode on all ports.

Under multicast-aware regime, when assigning traffic class to a packet,
the switch doesn't merely take the value prescribed by the QTCT
register. For BUM traffic, it instead assigns that value plus 8.

ETS elements for TCs 8..15 thus need to be configured as well. Extend
mlxsw_sp_port_ets_init() so that it maps each of them to the same
subgroup as their corresponding TC from the range 0..7, such that TCs X
and X+8 map to the same subgroup.

The existing code configures TCs with strict priority. So far this was
immaterial, because each TC had its own subgroup. Now that two TCs share
a subgroup it becomes important. TCs are prioritized in order of 7, 6,
..., 0, 15, 14, ..., 8: the higher TCs used for BUM traffic end up being
deprioritized. Since that's what's needed, keep that configuration as it
is, and configure the new TCs likewise.

Finally in mlxsw_sp_port_create(), invoke configuration of QTCTM to
enable MC-aware mode on each port.
Signed-off-by: default avatarPetr Machata <petrm@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d0a07d6a
...@@ -2793,6 +2793,13 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port) ...@@ -2793,6 +2793,13 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
false, 0); false, 0);
if (err) if (err)
return err; return err;
err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
MLXSW_REG_QEEC_HIERARCY_TC,
i + 8, i,
false, 0);
if (err)
return err;
} }
/* Make sure the max shaper is disabled in all hierarchies that /* Make sure the max shaper is disabled in all hierarchies that
...@@ -2830,6 +2837,16 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port) ...@@ -2830,6 +2837,16 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
return 0; return 0;
} }
static int mlxsw_sp_port_tc_mc_mode_set(struct mlxsw_sp_port *mlxsw_sp_port,
bool enable)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
char qtctm_pl[MLXSW_REG_QTCTM_LEN];
mlxsw_reg_qtctm_pack(qtctm_pl, mlxsw_sp_port->local_port, enable);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtctm), qtctm_pl);
}
static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
bool split, u8 module, u8 width, u8 lane) bool split, u8 module, u8 width, u8 lane)
{ {
...@@ -2958,6 +2975,13 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, ...@@ -2958,6 +2975,13 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
goto err_port_ets_init; goto err_port_ets_init;
} }
err = mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, true);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize TC MC mode\n",
mlxsw_sp_port->local_port);
goto err_port_tc_mc_mode;
}
/* ETS and buffers must be initialized before DCB. */ /* ETS and buffers must be initialized before DCB. */
err = mlxsw_sp_port_dcb_init(mlxsw_sp_port); err = mlxsw_sp_port_dcb_init(mlxsw_sp_port);
if (err) { if (err) {
...@@ -3014,6 +3038,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, ...@@ -3014,6 +3038,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
err_port_fids_init: err_port_fids_init:
mlxsw_sp_port_dcb_fini(mlxsw_sp_port); mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
err_port_dcb_init: err_port_dcb_init:
mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
err_port_tc_mc_mode:
err_port_ets_init: err_port_ets_init:
err_port_buffers_init: err_port_buffers_init:
err_port_admin_status_set: err_port_admin_status_set:
...@@ -3048,6 +3074,7 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) ...@@ -3048,6 +3074,7 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port); mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
mlxsw_sp_port_fids_fini(mlxsw_sp_port); mlxsw_sp_port_fids_fini(mlxsw_sp_port);
mlxsw_sp_port_dcb_fini(mlxsw_sp_port); mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT); mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
mlxsw_sp_port_module_unmap(mlxsw_sp_port); mlxsw_sp_port_module_unmap(mlxsw_sp_port);
kfree(mlxsw_sp_port->sample); kfree(mlxsw_sp_port->sample);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment