diff options
author | Petr Machata <petrm@mellanox.com> | 2020-06-21 11:34:33 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-06-22 16:32:11 -0700 |
commit | 3cc9a15a0bb1bde93d5430facda3f3e07c2d3d87 (patch) | |
tree | 36ee620feb9ca0fa3dc89140efa499ea6fa6c455 /drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | |
parent | 73f782d523ecf4a4ba1531266a02c53ab359c85b (diff) |
mlxsw: spectrum: Split handling of pedit mangle by chip type
Certain ACL actions are only available on some Spectrum revisions. In
particular, L4_PORT_ACTION is not available on Spectrum-1. Introduce a
new ops struct intended to hold these differences, mlxsw_sp_rulei_ops.
Prime it with a sole member, act_mangle_field, meant for handling of
pedit mangles.
Create two ops structures, one for Spectrum-1, the other for Spectrum-2
and above. Add callbacks for act_mangle_field and dispatch to the common
handler.
Invoke mlxsw_sp_rulei_ops.act_mangle_field from the field mangler
instead of calling the common handler directly.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c index 47da9ee0045d..cadcec6dbe19 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c @@ -563,11 +563,39 @@ mlxsw_sp_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp, case MLXSW_SP_ACL_MANGLE_FIELD_IP_ECN: return mlxsw_afa_block_append_qos_ecn(rulei->act_block, val, extack); + default: + return -EOPNOTSUPP; } +} - /* We shouldn't have gotten a match in the first place! */ - WARN_ONCE(1, "Unhandled mangle field"); - return -EINVAL; +static int mlxsw_sp1_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_rule_info *rulei, + struct mlxsw_sp_acl_mangle_action *mact, + u32 val, struct netlink_ext_ack *extack) +{ + int err; + + err = mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp, rulei, mact, val, extack); + if (err != -EOPNOTSUPP) + return err; + + NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field"); + return err; +} + +static int mlxsw_sp2_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_rule_info *rulei, + struct mlxsw_sp_acl_mangle_action *mact, + u32 val, struct netlink_ext_ack *extack) +{ + int err; + + err = mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp, rulei, mact, val, extack); + if (err != -EOPNOTSUPP) + return err; + + NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field"); + return err; } int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp, @@ -576,6 +604,7 @@ int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp, u32 offset, u32 mask, u32 val, struct netlink_ext_ack *extack) { + const struct mlxsw_sp_acl_rulei_ops *acl_rulei_ops = mlxsw_sp->acl_rulei_ops; struct mlxsw_sp_acl_mangle_action *mact; size_t i; @@ -585,13 +614,13 @@ int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp, mact->offset == offset && mact->mask == mask) { val >>= mact->shift; - return mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp, - rulei, mact, - val, extack); + return acl_rulei_ops->act_mangle_field(mlxsw_sp, + rulei, mact, + val, extack); } } - NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field"); + NL_SET_ERR_MSG_MOD(extack, "Unknown mangle field"); return -EINVAL; } @@ -930,3 +959,11 @@ int mlxsw_sp_acl_region_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, u32 val) return mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(mlxsw_sp, &acl->tcam, val); } + +struct mlxsw_sp_acl_rulei_ops mlxsw_sp1_acl_rulei_ops = { + .act_mangle_field = mlxsw_sp1_acl_rulei_act_mangle_field, +}; + +struct mlxsw_sp_acl_rulei_ops mlxsw_sp2_acl_rulei_ops = { + .act_mangle_field = mlxsw_sp2_acl_rulei_act_mangle_field, +}; |