mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
mlxsw: spectrum_acl: Split entry struct into entry and ventry
Do the split of entry struct so the new entry struct is related to the actual HW entry, whereas ventry struct is a SW abstration of that. This split prepares possibility for ventry to hold 2 HW entries which is needed for region ERP rehash flow. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b2d6b4d2be
commit
c4c2dc5429
3 changed files with 108 additions and 66 deletions
|
@ -640,7 +640,7 @@ mlxsw_sp_acl_rule_create(struct mlxsw_sp *mlxsw_sp,
|
|||
int err;
|
||||
|
||||
mlxsw_sp_acl_ruleset_ref_inc(ruleset);
|
||||
rule = kzalloc(sizeof(*rule) + ops->rule_priv_size(mlxsw_sp),
|
||||
rule = kzalloc(sizeof(*rule) + ops->rule_priv_size,
|
||||
GFP_KERNEL);
|
||||
if (!rule) {
|
||||
err = -ENOMEM;
|
||||
|
|
|
@ -190,11 +190,16 @@ struct mlxsw_sp_acl_tcam_vchunk {
|
|||
};
|
||||
|
||||
struct mlxsw_sp_acl_tcam_entry {
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk;
|
||||
struct mlxsw_sp_acl_tcam_ventry *ventry;
|
||||
unsigned long priv[0];
|
||||
/* priv has to be always the last item */
|
||||
};
|
||||
|
||||
struct mlxsw_sp_acl_tcam_ventry {
|
||||
struct mlxsw_sp_acl_tcam_entry *entry;
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk;
|
||||
};
|
||||
|
||||
static const struct rhashtable_params mlxsw_sp_acl_tcam_vchunk_ht_params = {
|
||||
.key_len = sizeof(unsigned int),
|
||||
.key_offset = offsetof(struct mlxsw_sp_acl_tcam_vchunk, priority),
|
||||
|
@ -828,65 +833,52 @@ mlxsw_sp_acl_tcam_vchunk_put(struct mlxsw_sp *mlxsw_sp,
|
|||
mlxsw_sp_acl_tcam_vchunk_destroy(mlxsw_sp, vchunk);
|
||||
}
|
||||
|
||||
static size_t mlxsw_sp_acl_tcam_entry_priv_size(struct mlxsw_sp *mlxsw_sp)
|
||||
static struct mlxsw_sp_acl_tcam_entry *
|
||||
mlxsw_sp_acl_tcam_entry_create(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_ventry *ventry,
|
||||
struct mlxsw_sp_acl_tcam_region *region,
|
||||
struct mlxsw_sp_acl_tcam_chunk *chunk,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
|
||||
|
||||
return ops->entry_priv_size;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_acl_tcam_entry_add(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_group *group,
|
||||
struct mlxsw_sp_acl_tcam_entry *entry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk;
|
||||
struct mlxsw_sp_acl_tcam_region *region;
|
||||
struct mlxsw_sp_acl_tcam_chunk *chunk;
|
||||
struct mlxsw_sp_acl_tcam_entry *entry;
|
||||
int err;
|
||||
|
||||
vchunk = mlxsw_sp_acl_tcam_vchunk_get(mlxsw_sp, group, rulei->priority,
|
||||
&rulei->values.elusage);
|
||||
if (IS_ERR(vchunk))
|
||||
return PTR_ERR(vchunk);
|
||||
|
||||
chunk = vchunk->chunk;
|
||||
region = vchunk->vregion->region;
|
||||
entry = kzalloc(sizeof(*entry) + ops->entry_priv_size, GFP_KERNEL);
|
||||
if (!entry)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
entry->ventry = ventry;
|
||||
|
||||
err = ops->entry_add(mlxsw_sp, region->priv, chunk->priv,
|
||||
entry->priv, rulei);
|
||||
if (err)
|
||||
goto err_entry_add;
|
||||
entry->vchunk = vchunk;
|
||||
|
||||
return 0;
|
||||
return entry;
|
||||
|
||||
err_entry_add:
|
||||
mlxsw_sp_acl_tcam_vchunk_put(mlxsw_sp, vchunk);
|
||||
return err;
|
||||
kfree(entry);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static void mlxsw_sp_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_entry *entry)
|
||||
static void mlxsw_sp_acl_tcam_entry_destroy(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_region *region,
|
||||
struct mlxsw_sp_acl_tcam_chunk *chunk,
|
||||
struct mlxsw_sp_acl_tcam_entry *entry)
|
||||
{
|
||||
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk = entry->vchunk;
|
||||
struct mlxsw_sp_acl_tcam_chunk *chunk = vchunk->chunk;
|
||||
struct mlxsw_sp_acl_tcam_region *region = vchunk->vregion->region;
|
||||
|
||||
ops->entry_del(mlxsw_sp, region->priv, chunk->priv, entry->priv);
|
||||
mlxsw_sp_acl_tcam_vchunk_put(mlxsw_sp, vchunk);
|
||||
kfree(entry);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_region *region,
|
||||
struct mlxsw_sp_acl_tcam_entry *entry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk = entry->vchunk;
|
||||
struct mlxsw_sp_acl_tcam_region *region = vchunk->vregion->region;
|
||||
|
||||
return ops->entry_action_replace(mlxsw_sp, region->priv,
|
||||
entry->priv, rulei);
|
||||
|
@ -894,17 +886,79 @@ mlxsw_sp_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
|||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_region *region,
|
||||
struct mlxsw_sp_acl_tcam_entry *entry,
|
||||
bool *activity)
|
||||
{
|
||||
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk = entry->vchunk;
|
||||
struct mlxsw_sp_acl_tcam_region *region = vchunk->vregion->region;
|
||||
|
||||
return ops->entry_activity_get(mlxsw_sp, region->priv,
|
||||
entry->priv, activity);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_acl_tcam_ventry_add(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_group *group,
|
||||
struct mlxsw_sp_acl_tcam_ventry *ventry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk;
|
||||
int err;
|
||||
|
||||
vchunk = mlxsw_sp_acl_tcam_vchunk_get(mlxsw_sp, group, rulei->priority,
|
||||
&rulei->values.elusage);
|
||||
if (IS_ERR(vchunk))
|
||||
return PTR_ERR(vchunk);
|
||||
|
||||
ventry->vchunk = vchunk;
|
||||
ventry->entry = mlxsw_sp_acl_tcam_entry_create(mlxsw_sp, ventry,
|
||||
vchunk->vregion->region,
|
||||
vchunk->chunk, rulei);
|
||||
if (IS_ERR(ventry->entry)) {
|
||||
err = PTR_ERR(ventry->entry);
|
||||
goto err_entry_create;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_entry_create:
|
||||
mlxsw_sp_acl_tcam_vchunk_put(mlxsw_sp, vchunk);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_acl_tcam_ventry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_ventry *ventry)
|
||||
{
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk = ventry->vchunk;
|
||||
|
||||
mlxsw_sp_acl_tcam_entry_destroy(mlxsw_sp, vchunk->vregion->region,
|
||||
vchunk->chunk, ventry->entry);
|
||||
mlxsw_sp_acl_tcam_vchunk_put(mlxsw_sp, vchunk);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_ventry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_ventry *ventry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk = ventry->vchunk;
|
||||
|
||||
return mlxsw_sp_acl_tcam_entry_action_replace(mlxsw_sp,
|
||||
vchunk->vregion->region,
|
||||
ventry->entry, rulei);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_ventry_activity_get(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_ventry *ventry,
|
||||
bool *activity)
|
||||
{
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk = ventry->vchunk;
|
||||
|
||||
return mlxsw_sp_acl_tcam_entry_activity_get(mlxsw_sp,
|
||||
vchunk->vregion->region,
|
||||
ventry->entry, activity);
|
||||
}
|
||||
|
||||
static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv4[] = {
|
||||
MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
|
||||
MLXSW_AFK_ELEMENT_DMAC_32_47,
|
||||
|
@ -959,7 +1013,7 @@ struct mlxsw_sp_acl_tcam_flower_ruleset {
|
|||
};
|
||||
|
||||
struct mlxsw_sp_acl_tcam_flower_rule {
|
||||
struct mlxsw_sp_acl_tcam_entry entry;
|
||||
struct mlxsw_sp_acl_tcam_ventry ventry;
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -1017,12 +1071,6 @@ mlxsw_sp_acl_tcam_flower_ruleset_group_id(void *ruleset_priv)
|
|||
return mlxsw_sp_acl_tcam_group_id(&ruleset->group);
|
||||
}
|
||||
|
||||
static size_t mlxsw_sp_acl_tcam_flower_rule_priv_size(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
return sizeof(struct mlxsw_sp_acl_tcam_flower_rule) +
|
||||
mlxsw_sp_acl_tcam_entry_priv_size(mlxsw_sp);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_flower_rule_add(struct mlxsw_sp *mlxsw_sp,
|
||||
void *ruleset_priv, void *rule_priv,
|
||||
|
@ -1031,8 +1079,8 @@ mlxsw_sp_acl_tcam_flower_rule_add(struct mlxsw_sp *mlxsw_sp,
|
|||
struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
|
||||
struct mlxsw_sp_acl_tcam_flower_rule *rule = rule_priv;
|
||||
|
||||
return mlxsw_sp_acl_tcam_entry_add(mlxsw_sp, &ruleset->group,
|
||||
&rule->entry, rulei);
|
||||
return mlxsw_sp_acl_tcam_ventry_add(mlxsw_sp, &ruleset->group,
|
||||
&rule->ventry, rulei);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1040,7 +1088,7 @@ mlxsw_sp_acl_tcam_flower_rule_del(struct mlxsw_sp *mlxsw_sp, void *rule_priv)
|
|||
{
|
||||
struct mlxsw_sp_acl_tcam_flower_rule *rule = rule_priv;
|
||||
|
||||
mlxsw_sp_acl_tcam_entry_del(mlxsw_sp, &rule->entry);
|
||||
mlxsw_sp_acl_tcam_ventry_del(mlxsw_sp, &rule->ventry);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1057,8 +1105,8 @@ mlxsw_sp_acl_tcam_flower_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
|
|||
{
|
||||
struct mlxsw_sp_acl_tcam_flower_rule *rule = rule_priv;
|
||||
|
||||
return mlxsw_sp_acl_tcam_entry_activity_get(mlxsw_sp, &rule->entry,
|
||||
activity);
|
||||
return mlxsw_sp_acl_tcam_ventry_activity_get(mlxsw_sp, &rule->ventry,
|
||||
activity);
|
||||
}
|
||||
|
||||
static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_flower_ops = {
|
||||
|
@ -1068,7 +1116,7 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_flower_ops = {
|
|||
.ruleset_bind = mlxsw_sp_acl_tcam_flower_ruleset_bind,
|
||||
.ruleset_unbind = mlxsw_sp_acl_tcam_flower_ruleset_unbind,
|
||||
.ruleset_group_id = mlxsw_sp_acl_tcam_flower_ruleset_group_id,
|
||||
.rule_priv_size = mlxsw_sp_acl_tcam_flower_rule_priv_size,
|
||||
.rule_priv_size = sizeof(struct mlxsw_sp_acl_tcam_flower_rule),
|
||||
.rule_add = mlxsw_sp_acl_tcam_flower_rule_add,
|
||||
.rule_del = mlxsw_sp_acl_tcam_flower_rule_del,
|
||||
.rule_action_replace = mlxsw_sp_acl_tcam_flower_rule_action_replace,
|
||||
|
@ -1081,7 +1129,7 @@ struct mlxsw_sp_acl_tcam_mr_ruleset {
|
|||
};
|
||||
|
||||
struct mlxsw_sp_acl_tcam_mr_rule {
|
||||
struct mlxsw_sp_acl_tcam_entry entry;
|
||||
struct mlxsw_sp_acl_tcam_ventry ventry;
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -1155,12 +1203,6 @@ mlxsw_sp_acl_tcam_mr_ruleset_group_id(void *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,
|
||||
|
@ -1169,8 +1211,8 @@ mlxsw_sp_acl_tcam_mr_rule_add(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
|
|||
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);
|
||||
return mlxsw_sp_acl_tcam_ventry_add(mlxsw_sp, &ruleset->group,
|
||||
&rule->ventry, rulei);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1178,7 +1220,7 @@ 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);
|
||||
mlxsw_sp_acl_tcam_ventry_del(mlxsw_sp, &rule->ventry);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1188,8 +1230,8 @@ mlxsw_sp_acl_tcam_mr_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
|
|||
{
|
||||
struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
|
||||
|
||||
return mlxsw_sp_acl_tcam_entry_action_replace(mlxsw_sp, &rule->entry,
|
||||
rulei);
|
||||
return mlxsw_sp_acl_tcam_ventry_action_replace(mlxsw_sp, &rule->ventry,
|
||||
rulei);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1198,8 +1240,8 @@ mlxsw_sp_acl_tcam_mr_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
|
|||
{
|
||||
struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
|
||||
|
||||
return mlxsw_sp_acl_tcam_entry_activity_get(mlxsw_sp, &rule->entry,
|
||||
activity);
|
||||
return mlxsw_sp_acl_tcam_ventry_activity_get(mlxsw_sp, &rule->ventry,
|
||||
activity);
|
||||
}
|
||||
|
||||
static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = {
|
||||
|
@ -1209,7 +1251,7 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = {
|
|||
.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_priv_size = sizeof(struct mlxsw_sp_acl_tcam_mr_rule),
|
||||
.rule_add = mlxsw_sp_acl_tcam_mr_rule_add,
|
||||
.rule_del = mlxsw_sp_acl_tcam_mr_rule_del,
|
||||
.rule_action_replace = mlxsw_sp_acl_tcam_mr_rule_action_replace,
|
||||
|
|
|
@ -43,7 +43,7 @@ struct mlxsw_sp_acl_profile_ops {
|
|||
struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
bool ingress);
|
||||
u16 (*ruleset_group_id)(void *ruleset_priv);
|
||||
size_t (*rule_priv_size)(struct mlxsw_sp *mlxsw_sp);
|
||||
size_t rule_priv_size;
|
||||
int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
|
||||
void *ruleset_priv, void *rule_priv,
|
||||
struct mlxsw_sp_acl_rule_info *rulei);
|
||||
|
|
Loading…
Reference in a new issue