From: Ido Schimmel Date: Fri, 10 Jul 2020 21:55:08 +0000 (+0300) Subject: mlxsw: spectrum_span: Add support for global mirroring triggers X-Git-Tag: Ubuntu-5.13.0-19.19~5372^2~271^2~7 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=ab8c06b7b42cf9e756a720931a0939cd0d56786a;p=mirror_ubuntu-jammy-kernel.git mlxsw: spectrum_span: Add support for global mirroring triggers Global mirroring triggers are triggers that are only keyed by their trigger, as opposed to per-port triggers, which are keyed by their trigger and port. Such triggers allow mirroring packets that were tail/early dropped or ECN marked to a SPAN agent. Implement the previously added trigger operations for these global triggers. Since such triggers are only supported from Spectrum-2 onwards, have the Spectrum-1 operations return an error. Signed-off-by: Ido Schimmel Reviewed-by: Petr Machata Reviewed-by: Jiri Pirko Signed-off-by: Petr Machata Signed-off-by: David S. Miller --- diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c index b20422dde147..fa223c1351b4 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c @@ -49,6 +49,7 @@ struct mlxsw_sp_span_trigger_entry { enum mlxsw_sp_span_trigger_type { MLXSW_SP_SPAN_TRIGGER_TYPE_PORT, + MLXSW_SP_SPAN_TRIGGER_TYPE_GLOBAL, }; struct mlxsw_sp_span_trigger_ops { @@ -1140,9 +1141,101 @@ mlxsw_sp_span_trigger_port_ops = { .matches = mlxsw_sp_span_trigger_port_matches, }; +static int +mlxsw_sp1_span_trigger_global_bind(struct mlxsw_sp_span_trigger_entry * + trigger_entry) +{ + return -EOPNOTSUPP; +} + +static void +mlxsw_sp1_span_trigger_global_unbind(struct mlxsw_sp_span_trigger_entry * + trigger_entry) +{ +} + +static bool +mlxsw_sp1_span_trigger_global_matches(struct mlxsw_sp_span_trigger_entry * + trigger_entry, + enum mlxsw_sp_span_trigger trigger, + struct mlxsw_sp_port *mlxsw_sp_port) +{ + WARN_ON_ONCE(1); + return false; +} + +static const struct mlxsw_sp_span_trigger_ops +mlxsw_sp1_span_trigger_global_ops = { + .bind = mlxsw_sp1_span_trigger_global_bind, + .unbind = mlxsw_sp1_span_trigger_global_unbind, + .matches = mlxsw_sp1_span_trigger_global_matches, +}; + +static const struct mlxsw_sp_span_trigger_ops * +mlxsw_sp1_span_trigger_ops_arr[] = { + [MLXSW_SP_SPAN_TRIGGER_TYPE_PORT] = &mlxsw_sp_span_trigger_port_ops, + [MLXSW_SP_SPAN_TRIGGER_TYPE_GLOBAL] = + &mlxsw_sp1_span_trigger_global_ops, +}; + +static int +mlxsw_sp2_span_trigger_global_bind(struct mlxsw_sp_span_trigger_entry * + trigger_entry) +{ + struct mlxsw_sp *mlxsw_sp = trigger_entry->span->mlxsw_sp; + enum mlxsw_reg_mpagr_trigger trigger; + char mpagr_pl[MLXSW_REG_MPAGR_LEN]; + + switch (trigger_entry->trigger) { + case MLXSW_SP_SPAN_TRIGGER_TAIL_DROP: + trigger = MLXSW_REG_MPAGR_TRIGGER_INGRESS_SHARED_BUFFER; + break; + case MLXSW_SP_SPAN_TRIGGER_EARLY_DROP: + trigger = MLXSW_REG_MPAGR_TRIGGER_INGRESS_WRED; + break; + case MLXSW_SP_SPAN_TRIGGER_ECN: + trigger = MLXSW_REG_MPAGR_TRIGGER_EGRESS_ECN; + break; + default: + WARN_ON_ONCE(1); + return -EINVAL; + } + + mlxsw_reg_mpagr_pack(mpagr_pl, trigger, trigger_entry->parms.span_id, + 1); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpagr), mpagr_pl); +} + +static void +mlxsw_sp2_span_trigger_global_unbind(struct mlxsw_sp_span_trigger_entry * + trigger_entry) +{ + /* There is no unbinding for global triggers. The trigger should be + * disabled on all ports by now. + */ +} + +static bool +mlxsw_sp2_span_trigger_global_matches(struct mlxsw_sp_span_trigger_entry * + trigger_entry, + enum mlxsw_sp_span_trigger trigger, + struct mlxsw_sp_port *mlxsw_sp_port) +{ + return trigger_entry->trigger == trigger; +} + +static const struct mlxsw_sp_span_trigger_ops +mlxsw_sp2_span_trigger_global_ops = { + .bind = mlxsw_sp2_span_trigger_global_bind, + .unbind = mlxsw_sp2_span_trigger_global_unbind, + .matches = mlxsw_sp2_span_trigger_global_matches, +}; + static const struct mlxsw_sp_span_trigger_ops * -mlxsw_sp_span_trigger_ops_arr[] = { +mlxsw_sp2_span_trigger_ops_arr[] = { [MLXSW_SP_SPAN_TRIGGER_TYPE_PORT] = &mlxsw_sp_span_trigger_port_ops, + [MLXSW_SP_SPAN_TRIGGER_TYPE_GLOBAL] = + &mlxsw_sp2_span_trigger_global_ops, }; static void @@ -1156,6 +1249,11 @@ mlxsw_sp_span_trigger_ops_set(struct mlxsw_sp_span_trigger_entry *trigger_entry) case MLXSW_SP_SPAN_TRIGGER_EGRESS: type = MLXSW_SP_SPAN_TRIGGER_TYPE_PORT; break; + case MLXSW_SP_SPAN_TRIGGER_TAIL_DROP: /* fall-through */ + case MLXSW_SP_SPAN_TRIGGER_EARLY_DROP: /* fall-through */ + case MLXSW_SP_SPAN_TRIGGER_ECN: + type = MLXSW_SP_SPAN_TRIGGER_TYPE_GLOBAL; + break; default: WARN_ON_ONCE(1); return; @@ -1286,7 +1384,7 @@ void mlxsw_sp_span_agent_unbind(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp1_span_init(struct mlxsw_sp *mlxsw_sp) { - mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp_span_trigger_ops_arr; + mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp1_span_trigger_ops_arr; return 0; } @@ -1303,7 +1401,7 @@ const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops = { static int mlxsw_sp2_span_init(struct mlxsw_sp *mlxsw_sp) { - mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp_span_trigger_ops_arr; + mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp2_span_trigger_ops_arr; return 0; } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h index b9acecaf6ee2..bb7939b3f09c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h @@ -26,6 +26,9 @@ struct mlxsw_sp_span_parms { enum mlxsw_sp_span_trigger { MLXSW_SP_SPAN_TRIGGER_INGRESS, MLXSW_SP_SPAN_TRIGGER_EGRESS, + MLXSW_SP_SPAN_TRIGGER_TAIL_DROP, + MLXSW_SP_SPAN_TRIGGER_EARLY_DROP, + MLXSW_SP_SPAN_TRIGGER_ECN, }; struct mlxsw_sp_span_trigger_parms {