Commit 1a29d293 authored by Nir Dotan's avatar Nir Dotan Committed by David S. Miller

mlxsw: spectrum_acl: Add multicast router profile operations

Add specific ACL operations needed for programming multicast routing ACL
groups and routes.
Signed-off-by: default avatarNir Dotan <nird@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent add4550f
......@@ -572,6 +572,7 @@ struct mlxsw_sp_acl_ruleset;
/* spectrum_acl.c */
enum mlxsw_sp_acl_profile {
MLXSW_SP_ACL_PROFILE_FLOWER,
MLXSW_SP_ACL_PROFILE_MR,
};
struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl);
......
......@@ -848,6 +848,15 @@ struct mlxsw_sp_acl_tcam_flower_rule {
struct mlxsw_sp_acl_tcam_entry entry;
};
struct mlxsw_sp_acl_tcam_mr_ruleset {
struct mlxsw_sp_acl_tcam_chunk *chunk;
struct mlxsw_sp_acl_tcam_group group;
};
struct mlxsw_sp_acl_tcam_mr_rule {
struct mlxsw_sp_acl_tcam_entry entry;
};
static int
mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam *tcam,
......@@ -952,9 +961,129 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_flower_ops = {
.rule_activity_get = mlxsw_sp_acl_tcam_flower_rule_activity_get,
};
static int
mlxsw_sp_acl_tcam_mr_ruleset_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam *tcam,
void *ruleset_priv,
struct mlxsw_afk_element_usage *tmplt_elusage)
{
struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
int err;
err = mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group,
mlxsw_sp_acl_tcam_patterns,
MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
tmplt_elusage);
if (err)
return err;
/* For most of the TCAM clients it would make sense to take a tcam chunk
* only when the first rule is written. This is not the case for
* multicast router as it is required to bind the multicast router to a
* specific ACL Group ID which must exist in HW before multicast router
* is initialized.
*/
ruleset->chunk = mlxsw_sp_acl_tcam_chunk_get(mlxsw_sp, &ruleset->group,
1, tmplt_elusage);
if (IS_ERR(ruleset->chunk)) {
err = PTR_ERR(ruleset->chunk);
goto err_chunk_get;
}
return 0;
err_chunk_get:
mlxsw_sp_acl_tcam_group_del(mlxsw_sp, &ruleset->group);
return err;
}
static void
mlxsw_sp_acl_tcam_mr_ruleset_del(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv)
{
struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
mlxsw_sp_acl_tcam_chunk_put(mlxsw_sp, ruleset->chunk);
mlxsw_sp_acl_tcam_group_del(mlxsw_sp, &ruleset->group);
}
static int
mlxsw_sp_acl_tcam_mr_ruleset_bind(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress)
{
/* Binding is done when initializing multicast router */
return 0;
}
static void
mlxsw_sp_acl_tcam_mr_ruleset_unbind(struct mlxsw_sp *mlxsw_sp,
void *ruleset_priv,
struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress)
{
}
static u16
mlxsw_sp_acl_tcam_mr_ruleset_group_id(void *ruleset_priv)
{
struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
return mlxsw_sp_acl_tcam_group_id(&ruleset->group);
}
static size_t mlxsw_sp_acl_tcam_mr_rule_priv_size(struct mlxsw_sp *mlxsw_sp)
{
return sizeof(struct mlxsw_sp_acl_tcam_mr_rule) +
mlxsw_sp_acl_tcam_entry_priv_size(mlxsw_sp);
}
static int
mlxsw_sp_acl_tcam_mr_rule_add(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
void *rule_priv,
struct mlxsw_sp_acl_rule_info *rulei)
{
struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
return mlxsw_sp_acl_tcam_entry_add(mlxsw_sp, &ruleset->group,
&rule->entry, rulei);
}
static void
mlxsw_sp_acl_tcam_mr_rule_del(struct mlxsw_sp *mlxsw_sp, void *rule_priv)
{
struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
mlxsw_sp_acl_tcam_entry_del(mlxsw_sp, &rule->entry);
}
static int
mlxsw_sp_acl_tcam_mr_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
void *rule_priv, bool *activity)
{
struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
return mlxsw_sp_acl_tcam_entry_activity_get(mlxsw_sp, &rule->entry,
activity);
}
static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = {
.ruleset_priv_size = sizeof(struct mlxsw_sp_acl_tcam_mr_ruleset),
.ruleset_add = mlxsw_sp_acl_tcam_mr_ruleset_add,
.ruleset_del = mlxsw_sp_acl_tcam_mr_ruleset_del,
.ruleset_bind = mlxsw_sp_acl_tcam_mr_ruleset_bind,
.ruleset_unbind = mlxsw_sp_acl_tcam_mr_ruleset_unbind,
.ruleset_group_id = mlxsw_sp_acl_tcam_mr_ruleset_group_id,
.rule_priv_size = mlxsw_sp_acl_tcam_mr_rule_priv_size,
.rule_add = mlxsw_sp_acl_tcam_mr_rule_add,
.rule_del = mlxsw_sp_acl_tcam_mr_rule_del,
.rule_activity_get = mlxsw_sp_acl_tcam_mr_rule_activity_get,
};
static const struct mlxsw_sp_acl_profile_ops *
mlxsw_sp_acl_tcam_profile_ops_arr[] = {
[MLXSW_SP_ACL_PROFILE_FLOWER] = &mlxsw_sp_acl_tcam_flower_ops,
[MLXSW_SP_ACL_PROFILE_MR] = &mlxsw_sp_acl_tcam_mr_ops,
};
const struct mlxsw_sp_acl_profile_ops *
......
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