提交 bab5c1cf 编写于 作者: J Jiri Pirko 提交者: David S. Miller

mlxsw: spectrum_acl: Add tcam init/fini ops

Add ops to be called on driver instance init and fini.
This is needed in order to be possible to do Spectrum-2 specific init
and fini work.
Signed-off-by: NJiri Pirko <jiri@mellanox.com>
Signed-off-by: NIdo Schimmel <idosch@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 64eccd00
...@@ -503,44 +503,14 @@ struct mlxsw_sp_acl_rule_info { ...@@ -503,44 +503,14 @@ struct mlxsw_sp_acl_rule_info {
unsigned int counter_index; unsigned int counter_index;
}; };
enum mlxsw_sp_acl_profile {
MLXSW_SP_ACL_PROFILE_FLOWER,
};
struct mlxsw_sp_acl_profile_ops {
size_t ruleset_priv_size;
int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
void *priv, void *ruleset_priv);
void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress);
void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
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);
int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
void *ruleset_priv, void *rule_priv,
struct mlxsw_sp_acl_rule_info *rulei);
void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
bool *activity);
};
struct mlxsw_sp_acl_ops {
size_t priv_size;
int (*init)(struct mlxsw_sp *mlxsw_sp, void *priv);
void (*fini)(struct mlxsw_sp *mlxsw_sp, void *priv);
const struct mlxsw_sp_acl_profile_ops *
(*profile_ops)(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_acl_profile profile);
};
struct mlxsw_sp_acl_block; struct mlxsw_sp_acl_block;
struct mlxsw_sp_acl_ruleset; struct mlxsw_sp_acl_ruleset;
/* spectrum_acl.c */ /* spectrum_acl.c */
enum mlxsw_sp_acl_profile {
MLXSW_SP_ACL_PROFILE_FLOWER,
};
struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl); struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl);
struct mlxsw_sp *mlxsw_sp_acl_block_mlxsw_sp(struct mlxsw_sp_acl_block *block); struct mlxsw_sp *mlxsw_sp_acl_block_mlxsw_sp(struct mlxsw_sp_acl_block *block);
unsigned int mlxsw_sp_acl_block_rule_count(struct mlxsw_sp_acl_block *block); unsigned int mlxsw_sp_acl_block_rule_count(struct mlxsw_sp_acl_block *block);
...@@ -633,10 +603,15 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp); ...@@ -633,10 +603,15 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp); void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp);
/* spectrum_acl_tcam.c */ /* spectrum_acl_tcam.c */
struct mlxsw_sp_acl_tcam;
struct mlxsw_sp_acl_tcam_region; struct mlxsw_sp_acl_tcam_region;
struct mlxsw_sp_acl_tcam_ops { struct mlxsw_sp_acl_tcam_ops {
enum mlxsw_reg_ptar_key_type key_type; enum mlxsw_reg_ptar_key_type key_type;
size_t priv_size;
int (*init)(struct mlxsw_sp *mlxsw_sp, void *priv,
struct mlxsw_sp_acl_tcam *tcam);
void (*fini)(struct mlxsw_sp *mlxsw_sp, void *priv);
size_t region_priv_size; size_t region_priv_size;
int (*region_init)(struct mlxsw_sp *mlxsw_sp, void *region_priv, int (*region_init)(struct mlxsw_sp *mlxsw_sp, void *region_priv,
struct mlxsw_sp_acl_tcam_region *region); struct mlxsw_sp_acl_tcam_region *region);
......
...@@ -58,6 +58,16 @@ struct mlxsw_sp1_acl_tcam_entry { ...@@ -58,6 +58,16 @@ struct mlxsw_sp1_acl_tcam_entry {
struct mlxsw_sp_acl_ctcam_entry centry; struct mlxsw_sp_acl_ctcam_entry centry;
}; };
static int mlxsw_sp1_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv,
struct mlxsw_sp_acl_tcam *tcam)
{
return 0;
}
static void mlxsw_sp1_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, void *priv)
{
}
static int static int
mlxsw_sp1_acl_ctcam_region_catchall_add(struct mlxsw_sp *mlxsw_sp, mlxsw_sp1_acl_ctcam_region_catchall_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp1_acl_tcam_region *region) struct mlxsw_sp1_acl_tcam_region *region)
...@@ -218,6 +228,9 @@ mlxsw_sp1_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp, ...@@ -218,6 +228,9 @@ mlxsw_sp1_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_acl_tcam_ops mlxsw_sp1_acl_tcam_ops = { const struct mlxsw_sp_acl_tcam_ops mlxsw_sp1_acl_tcam_ops = {
.key_type = MLXSW_REG_PTAR_KEY_TYPE_FLEX, .key_type = MLXSW_REG_PTAR_KEY_TYPE_FLEX,
.priv_size = 0,
.init = mlxsw_sp1_acl_tcam_init,
.fini = mlxsw_sp1_acl_tcam_fini,
.region_priv_size = sizeof(struct mlxsw_sp1_acl_tcam_region), .region_priv_size = sizeof(struct mlxsw_sp1_acl_tcam_region),
.region_init = mlxsw_sp1_acl_tcam_region_init, .region_init = mlxsw_sp1_acl_tcam_region_init,
.region_fini = mlxsw_sp1_acl_tcam_region_fini, .region_fini = mlxsw_sp1_acl_tcam_region_fini,
......
...@@ -55,7 +55,6 @@ struct mlxsw_sp_acl { ...@@ -55,7 +55,6 @@ struct mlxsw_sp_acl {
struct mlxsw_sp *mlxsw_sp; struct mlxsw_sp *mlxsw_sp;
struct mlxsw_afk *afk; struct mlxsw_afk *afk;
struct mlxsw_sp_fid *dummy_fid; struct mlxsw_sp_fid *dummy_fid;
const struct mlxsw_sp_acl_ops *ops;
struct rhashtable ruleset_ht; struct rhashtable ruleset_ht;
struct list_head rules; struct list_head rules;
struct { struct {
...@@ -63,8 +62,7 @@ struct mlxsw_sp_acl { ...@@ -63,8 +62,7 @@ struct mlxsw_sp_acl {
unsigned long interval; /* ms */ unsigned long interval; /* ms */
#define MLXSW_SP_ACL_RULE_ACTIVITY_UPDATE_PERIOD_MS 1000 #define MLXSW_SP_ACL_RULE_ACTIVITY_UPDATE_PERIOD_MS 1000
} rule_activity_update; } rule_activity_update;
unsigned long priv[0]; struct mlxsw_sp_acl_tcam tcam;
/* priv has to be always the last item */
}; };
struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl) struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl)
...@@ -340,7 +338,7 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp, ...@@ -340,7 +338,7 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
goto err_rhashtable_init; goto err_rhashtable_init;
err = ops->ruleset_add(mlxsw_sp, acl->priv, ruleset->priv); err = ops->ruleset_add(mlxsw_sp, &acl->tcam, ruleset->priv);
if (err) if (err)
goto err_ops_ruleset_add; goto err_ops_ruleset_add;
...@@ -410,7 +408,7 @@ mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp, ...@@ -410,7 +408,7 @@ mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl *acl = mlxsw_sp->acl; struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_ruleset *ruleset;
ops = acl->ops->profile_ops(mlxsw_sp, profile); ops = mlxsw_sp_acl_tcam_profile_ops(mlxsw_sp, profile);
if (!ops) if (!ops)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
ruleset = __mlxsw_sp_acl_ruleset_lookup(acl, block, chain_index, ops); ruleset = __mlxsw_sp_acl_ruleset_lookup(acl, block, chain_index, ops);
...@@ -428,7 +426,7 @@ mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp, ...@@ -428,7 +426,7 @@ mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl *acl = mlxsw_sp->acl; struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_ruleset *ruleset;
ops = acl->ops->profile_ops(mlxsw_sp, profile); ops = mlxsw_sp_acl_tcam_profile_ops(mlxsw_sp, profile);
if (!ops) if (!ops)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -827,12 +825,13 @@ int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp, ...@@ -827,12 +825,13 @@ int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp) int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
{ {
const struct mlxsw_sp_acl_ops *acl_ops = &mlxsw_sp_acl_tcam_ops;
struct mlxsw_sp_fid *fid; struct mlxsw_sp_fid *fid;
struct mlxsw_sp_acl *acl; struct mlxsw_sp_acl *acl;
size_t alloc_size;
int err; int err;
acl = kzalloc(sizeof(*acl) + acl_ops->priv_size, GFP_KERNEL); alloc_size = sizeof(*acl) + mlxsw_sp_acl_tcam_priv_size(mlxsw_sp);
acl = kzalloc(alloc_size, GFP_KERNEL);
if (!acl) if (!acl)
return -ENOMEM; return -ENOMEM;
mlxsw_sp->acl = acl; mlxsw_sp->acl = acl;
...@@ -859,12 +858,10 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp) ...@@ -859,12 +858,10 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
acl->dummy_fid = fid; acl->dummy_fid = fid;
INIT_LIST_HEAD(&acl->rules); INIT_LIST_HEAD(&acl->rules);
err = acl_ops->init(mlxsw_sp, acl->priv); err = mlxsw_sp_acl_tcam_init(mlxsw_sp, &acl->tcam);
if (err) if (err)
goto err_acl_ops_init; goto err_acl_ops_init;
acl->ops = acl_ops;
/* Create the delayed work for the rule activity_update */ /* Create the delayed work for the rule activity_update */
INIT_DELAYED_WORK(&acl->rule_activity_update.dw, INIT_DELAYED_WORK(&acl->rule_activity_update.dw,
mlxsw_sp_acl_rul_activity_update_work); mlxsw_sp_acl_rul_activity_update_work);
...@@ -886,10 +883,9 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp) ...@@ -886,10 +883,9 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp) void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_sp_acl *acl = mlxsw_sp->acl; struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
const struct mlxsw_sp_acl_ops *acl_ops = acl->ops;
cancel_delayed_work_sync(&mlxsw_sp->acl->rule_activity_update.dw); cancel_delayed_work_sync(&mlxsw_sp->acl->rule_activity_update.dw);
acl_ops->fini(mlxsw_sp, acl->priv); mlxsw_sp_acl_tcam_fini(mlxsw_sp, &acl->tcam);
WARN_ON(!list_empty(&acl->rules)); WARN_ON(!list_empty(&acl->rules));
mlxsw_sp_fid_put(acl->dummy_fid); mlxsw_sp_fid_put(acl->dummy_fid);
rhashtable_destroy(&acl->ruleset_ht); rhashtable_destroy(&acl->ruleset_ht);
......
...@@ -47,17 +47,17 @@ ...@@ -47,17 +47,17 @@
#include "spectrum_acl_tcam.h" #include "spectrum_acl_tcam.h"
#include "core_acl_flex_keys.h" #include "core_acl_flex_keys.h"
struct mlxsw_sp_acl_tcam { size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp)
unsigned long *used_regions; /* bit array */ {
unsigned int max_regions; const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
unsigned long *used_groups; /* bit array */
unsigned int max_groups; return ops->priv_size;
unsigned int max_group_size; }
};
static int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv) int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam *tcam)
{ {
struct mlxsw_sp_acl_tcam *tcam = priv; const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
u64 max_tcam_regions; u64 max_tcam_regions;
u64 max_regions; u64 max_regions;
u64 max_groups; u64 max_groups;
...@@ -88,17 +88,26 @@ static int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv) ...@@ -88,17 +88,26 @@ static int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv)
tcam->max_groups = max_groups; tcam->max_groups = max_groups;
tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
ACL_MAX_GROUP_SIZE); ACL_MAX_GROUP_SIZE);
err = ops->init(mlxsw_sp, tcam->priv, tcam);
if (err)
goto err_tcam_init;
return 0; return 0;
err_tcam_init:
kfree(tcam->used_groups);
err_alloc_used_groups: err_alloc_used_groups:
kfree(tcam->used_regions); kfree(tcam->used_regions);
return err; return err;
} }
static void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, void *priv) void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam *tcam)
{ {
struct mlxsw_sp_acl_tcam *tcam = priv; const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
ops->fini(mlxsw_sp, tcam->priv);
kfree(tcam->used_groups); kfree(tcam->used_groups);
kfree(tcam->used_regions); kfree(tcam->used_regions);
} }
...@@ -827,10 +836,10 @@ struct mlxsw_sp_acl_tcam_flower_rule { ...@@ -827,10 +836,10 @@ struct mlxsw_sp_acl_tcam_flower_rule {
static int static int
mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp,
void *priv, void *ruleset_priv) struct mlxsw_sp_acl_tcam *tcam,
void *ruleset_priv)
{ {
struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv; struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
struct mlxsw_sp_acl_tcam *tcam = priv;
return mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group, return mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group,
mlxsw_sp_acl_tcam_patterns, mlxsw_sp_acl_tcam_patterns,
...@@ -932,7 +941,7 @@ mlxsw_sp_acl_tcam_profile_ops_arr[] = { ...@@ -932,7 +941,7 @@ mlxsw_sp_acl_tcam_profile_ops_arr[] = {
[MLXSW_SP_ACL_PROFILE_FLOWER] = &mlxsw_sp_acl_tcam_flower_ops, [MLXSW_SP_ACL_PROFILE_FLOWER] = &mlxsw_sp_acl_tcam_flower_ops,
}; };
static const struct mlxsw_sp_acl_profile_ops * const struct mlxsw_sp_acl_profile_ops *
mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_acl_profile profile) enum mlxsw_sp_acl_profile profile)
{ {
...@@ -945,10 +954,3 @@ mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp, ...@@ -945,10 +954,3 @@ mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
return NULL; return NULL;
return ops; return ops;
} }
const struct mlxsw_sp_acl_ops mlxsw_sp_acl_tcam_ops = {
.priv_size = sizeof(struct mlxsw_sp_acl_tcam),
.init = mlxsw_sp_acl_tcam_init,
.fini = mlxsw_sp_acl_tcam_fini,
.profile_ops = mlxsw_sp_acl_tcam_profile_ops,
};
...@@ -42,7 +42,46 @@ ...@@ -42,7 +42,46 @@
#include "spectrum.h" #include "spectrum.h"
#include "core_acl_flex_keys.h" #include "core_acl_flex_keys.h"
extern const struct mlxsw_sp_acl_ops mlxsw_sp_acl_tcam_ops; struct mlxsw_sp_acl_tcam {
unsigned long *used_regions; /* bit array */
unsigned int max_regions;
unsigned long *used_groups; /* bit array */
unsigned int max_groups;
unsigned int max_group_size;
unsigned long priv[0];
/* priv has to be always the last item */
};
size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp);
int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam *tcam);
void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam *tcam);
struct mlxsw_sp_acl_profile_ops {
size_t ruleset_priv_size;
int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv);
void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress);
void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
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);
int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
void *ruleset_priv, void *rule_priv,
struct mlxsw_sp_acl_rule_info *rulei);
void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
bool *activity);
};
const struct mlxsw_sp_acl_profile_ops *
mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_acl_profile profile);
#define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
#define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册