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: 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
64eccd0066
commit
bab5c1cfb7
@ -503,44 +503,14 @@ struct mlxsw_sp_acl_rule_info {
|
||||
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_ruleset;
|
||||
|
||||
/* 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_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);
|
||||
@ -633,10 +603,15 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp);
|
||||
void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp);
|
||||
|
||||
/* spectrum_acl_tcam.c */
|
||||
struct mlxsw_sp_acl_tcam;
|
||||
struct mlxsw_sp_acl_tcam_region;
|
||||
|
||||
struct mlxsw_sp_acl_tcam_ops {
|
||||
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;
|
||||
int (*region_init)(struct mlxsw_sp *mlxsw_sp, void *region_priv,
|
||||
struct mlxsw_sp_acl_tcam_region *region);
|
||||
|
@ -58,6 +58,16 @@ struct mlxsw_sp1_acl_tcam_entry {
|
||||
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
|
||||
mlxsw_sp1_acl_ctcam_region_catchall_add(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp1_acl_tcam_region *region)
|
||||
@ -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 = {
|
||||
.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_init = mlxsw_sp1_acl_tcam_region_init,
|
||||
.region_fini = mlxsw_sp1_acl_tcam_region_fini,
|
||||
|
@ -55,7 +55,6 @@ struct mlxsw_sp_acl {
|
||||
struct mlxsw_sp *mlxsw_sp;
|
||||
struct mlxsw_afk *afk;
|
||||
struct mlxsw_sp_fid *dummy_fid;
|
||||
const struct mlxsw_sp_acl_ops *ops;
|
||||
struct rhashtable ruleset_ht;
|
||||
struct list_head rules;
|
||||
struct {
|
||||
@ -63,8 +62,7 @@ struct mlxsw_sp_acl {
|
||||
unsigned long interval; /* ms */
|
||||
#define MLXSW_SP_ACL_RULE_ACTIVITY_UPDATE_PERIOD_MS 1000
|
||||
} rule_activity_update;
|
||||
unsigned long priv[0];
|
||||
/* priv has to be always the last item */
|
||||
struct mlxsw_sp_acl_tcam tcam;
|
||||
};
|
||||
|
||||
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,
|
||||
if (err)
|
||||
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)
|
||||
goto err_ops_ruleset_add;
|
||||
|
||||
@ -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_ruleset *ruleset;
|
||||
|
||||
ops = acl->ops->profile_ops(mlxsw_sp, profile);
|
||||
ops = mlxsw_sp_acl_tcam_profile_ops(mlxsw_sp, profile);
|
||||
if (!ops)
|
||||
return ERR_PTR(-EINVAL);
|
||||
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,
|
||||
struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
|
||||
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)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
const struct mlxsw_sp_acl_ops *acl_ops = &mlxsw_sp_acl_tcam_ops;
|
||||
struct mlxsw_sp_fid *fid;
|
||||
struct mlxsw_sp_acl *acl;
|
||||
size_t alloc_size;
|
||||
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)
|
||||
return -ENOMEM;
|
||||
mlxsw_sp->acl = acl;
|
||||
@ -859,12 +858,10 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
|
||||
acl->dummy_fid = fid;
|
||||
|
||||
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)
|
||||
goto err_acl_ops_init;
|
||||
|
||||
acl->ops = acl_ops;
|
||||
|
||||
/* Create the delayed work for the rule activity_update */
|
||||
INIT_DELAYED_WORK(&acl->rule_activity_update.dw,
|
||||
mlxsw_sp_acl_rul_activity_update_work);
|
||||
@ -886,10 +883,9 @@ err_afk_create:
|
||||
void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
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);
|
||||
acl_ops->fini(mlxsw_sp, acl->priv);
|
||||
mlxsw_sp_acl_tcam_fini(mlxsw_sp, &acl->tcam);
|
||||
WARN_ON(!list_empty(&acl->rules));
|
||||
mlxsw_sp_fid_put(acl->dummy_fid);
|
||||
rhashtable_destroy(&acl->ruleset_ht);
|
||||
|
@ -47,17 +47,17 @@
|
||||
#include "spectrum_acl_tcam.h"
|
||||
#include "core_acl_flex_keys.h"
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
static int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv)
|
||||
size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
struct mlxsw_sp_acl_tcam *tcam = priv;
|
||||
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
|
||||
|
||||
return ops->priv_size;
|
||||
}
|
||||
|
||||
int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam *tcam)
|
||||
{
|
||||
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
|
||||
u64 max_tcam_regions;
|
||||
u64 max_regions;
|
||||
u64 max_groups;
|
||||
@ -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_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
|
||||
ACL_MAX_GROUP_SIZE);
|
||||
|
||||
err = ops->init(mlxsw_sp, tcam->priv, tcam);
|
||||
if (err)
|
||||
goto err_tcam_init;
|
||||
|
||||
return 0;
|
||||
|
||||
err_tcam_init:
|
||||
kfree(tcam->used_groups);
|
||||
err_alloc_used_groups:
|
||||
kfree(tcam->used_regions);
|
||||
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_regions);
|
||||
}
|
||||
@ -827,10 +836,10 @@ struct mlxsw_sp_acl_tcam_flower_rule {
|
||||
|
||||
static int
|
||||
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 *tcam = priv;
|
||||
|
||||
return mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group,
|
||||
mlxsw_sp_acl_tcam_patterns,
|
||||
@ -932,7 +941,7 @@ mlxsw_sp_acl_tcam_profile_ops_arr[] = {
|
||||
[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,
|
||||
enum mlxsw_sp_acl_profile profile)
|
||||
{
|
||||
@ -945,10 +954,3 @@ mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
|
||||
return NULL;
|
||||
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 @@
|
||||
#include "spectrum.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_RESIZE_STEP 16
|
||||
|
Loading…
Reference in New Issue
Block a user