Commit a0a777b9 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum_acl: Start using A-TCAM

Now that all the pieces are in place we can start using the A-TCAM
instead of only using the C-TCAM. This allows for much higher scale and
better performance (to be improved further by follow-up patch sets).

Perform the integration with the A-TCAM and the eRP core by reverting
the changes introduced by "mlxsw: spectrum_acl: Enable C-TCAM only mode
in eRP core" and add calls from the C-TCAM code into the eRP core.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a8758b67
...@@ -2868,7 +2868,6 @@ static inline void mlxsw_reg_percr_pack(char *payload, u16 region_id) ...@@ -2868,7 +2868,6 @@ static inline void mlxsw_reg_percr_pack(char *payload, u16 region_id)
mlxsw_reg_percr_atcam_ignore_prune_set(payload, false); mlxsw_reg_percr_atcam_ignore_prune_set(payload, false);
mlxsw_reg_percr_ctcam_ignore_prune_set(payload, false); mlxsw_reg_percr_ctcam_ignore_prune_set(payload, false);
mlxsw_reg_percr_bf_bypass_set(payload, true); mlxsw_reg_percr_bf_bypass_set(payload, true);
memset(payload + 0x20, 0xff, 96);
} }
/* PERERP - Policy-Engine Region eRP Register /* PERERP - Policy-Engine Region eRP Register
......
...@@ -58,6 +58,26 @@ struct mlxsw_sp1_acl_tcam_entry { ...@@ -58,6 +58,26 @@ 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_ctcam_region_entry_insert(struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_ctcam_entry *centry,
const char *mask)
{
return 0;
}
static void
mlxsw_sp1_acl_ctcam_region_entry_remove(struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_ctcam_entry *centry)
{
}
static const struct mlxsw_sp_acl_ctcam_region_ops
mlxsw_sp1_acl_ctcam_region_ops = {
.entry_insert = mlxsw_sp1_acl_ctcam_region_entry_insert,
.entry_remove = mlxsw_sp1_acl_ctcam_region_entry_remove,
};
static int mlxsw_sp1_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv, static int mlxsw_sp1_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv,
struct mlxsw_sp_acl_tcam *tcam) struct mlxsw_sp_acl_tcam *tcam)
{ {
...@@ -129,7 +149,8 @@ mlxsw_sp1_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv, ...@@ -129,7 +149,8 @@ mlxsw_sp1_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv,
int err; int err;
err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &region->cregion, err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &region->cregion,
_region); _region,
&mlxsw_sp1_acl_ctcam_region_ops);
if (err) if (err)
return err; return err;
err = mlxsw_sp1_acl_ctcam_region_catchall_add(mlxsw_sp, region); err = mlxsw_sp1_acl_ctcam_region_catchall_add(mlxsw_sp, region);
......
...@@ -50,7 +50,7 @@ struct mlxsw_sp2_acl_tcam_region { ...@@ -50,7 +50,7 @@ struct mlxsw_sp2_acl_tcam_region {
}; };
struct mlxsw_sp2_acl_tcam_chunk { struct mlxsw_sp2_acl_tcam_chunk {
struct mlxsw_sp_acl_ctcam_chunk cchunk; struct mlxsw_sp_acl_atcam_chunk achunk;
}; };
struct mlxsw_sp2_acl_tcam_entry { struct mlxsw_sp2_acl_tcam_entry {
...@@ -58,6 +58,45 @@ struct mlxsw_sp2_acl_tcam_entry { ...@@ -58,6 +58,45 @@ struct mlxsw_sp2_acl_tcam_entry {
struct mlxsw_afa_block *act_block; struct mlxsw_afa_block *act_block;
}; };
static int
mlxsw_sp2_acl_ctcam_region_entry_insert(struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_ctcam_entry *centry,
const char *mask)
{
struct mlxsw_sp_acl_atcam_region *aregion;
struct mlxsw_sp_acl_atcam_entry *aentry;
struct mlxsw_sp_acl_erp *erp;
aregion = mlxsw_sp_acl_tcam_cregion_aregion(cregion);
aentry = mlxsw_sp_acl_tcam_centry_aentry(centry);
erp = mlxsw_sp_acl_erp_get(aregion, mask, true);
if (IS_ERR(erp))
return PTR_ERR(erp);
aentry->erp = erp;
return 0;
}
static void
mlxsw_sp2_acl_ctcam_region_entry_remove(struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_ctcam_entry *centry)
{
struct mlxsw_sp_acl_atcam_region *aregion;
struct mlxsw_sp_acl_atcam_entry *aentry;
aregion = mlxsw_sp_acl_tcam_cregion_aregion(cregion);
aentry = mlxsw_sp_acl_tcam_centry_aentry(centry);
mlxsw_sp_acl_erp_put(aregion, aentry->erp);
}
static const struct mlxsw_sp_acl_ctcam_region_ops
mlxsw_sp2_acl_ctcam_region_ops = {
.entry_insert = mlxsw_sp2_acl_ctcam_region_entry_insert,
.entry_remove = mlxsw_sp2_acl_ctcam_region_entry_remove,
};
static int mlxsw_sp2_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv, static int mlxsw_sp2_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv,
struct mlxsw_sp_acl_tcam *_tcam) struct mlxsw_sp_acl_tcam *_tcam)
{ {
...@@ -139,7 +178,8 @@ mlxsw_sp2_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv, ...@@ -139,7 +178,8 @@ mlxsw_sp2_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv,
region->region = _region; region->region = _region;
return mlxsw_sp_acl_atcam_region_init(mlxsw_sp, &tcam->atcam, return mlxsw_sp_acl_atcam_region_init(mlxsw_sp, &tcam->atcam,
&region->aregion, _region); &region->aregion, _region,
&mlxsw_sp2_acl_ctcam_region_ops);
} }
static void static void
...@@ -163,7 +203,7 @@ static void mlxsw_sp2_acl_tcam_chunk_init(void *region_priv, void *chunk_priv, ...@@ -163,7 +203,7 @@ static void mlxsw_sp2_acl_tcam_chunk_init(void *region_priv, void *chunk_priv,
struct mlxsw_sp2_acl_tcam_region *region = region_priv; struct mlxsw_sp2_acl_tcam_region *region = region_priv;
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv; struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
mlxsw_sp_acl_ctcam_chunk_init(&region->aregion.cregion, &chunk->cchunk, mlxsw_sp_acl_atcam_chunk_init(&region->aregion, &chunk->achunk,
priority); priority);
} }
...@@ -171,7 +211,7 @@ static void mlxsw_sp2_acl_tcam_chunk_fini(void *chunk_priv) ...@@ -171,7 +211,7 @@ static void mlxsw_sp2_acl_tcam_chunk_fini(void *chunk_priv)
{ {
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv; struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
mlxsw_sp_acl_ctcam_chunk_fini(&chunk->cchunk); mlxsw_sp_acl_atcam_chunk_fini(&chunk->achunk);
} }
static int mlxsw_sp2_acl_tcam_entry_add(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp2_acl_tcam_entry_add(struct mlxsw_sp *mlxsw_sp,
...@@ -184,9 +224,9 @@ static int mlxsw_sp2_acl_tcam_entry_add(struct mlxsw_sp *mlxsw_sp, ...@@ -184,9 +224,9 @@ static int mlxsw_sp2_acl_tcam_entry_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv; struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv;
entry->act_block = rulei->act_block; entry->act_block = rulei->act_block;
return mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, &region->aregion.cregion, return mlxsw_sp_acl_atcam_entry_add(mlxsw_sp, &region->aregion,
&chunk->cchunk, &chunk->achunk, &entry->aentry,
&entry->aentry.centry, rulei, true); rulei);
} }
static void mlxsw_sp2_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp, static void mlxsw_sp2_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
...@@ -197,8 +237,8 @@ static void mlxsw_sp2_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp, ...@@ -197,8 +237,8 @@ static void mlxsw_sp2_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv; struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv; struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv;
mlxsw_sp_acl_ctcam_entry_del(mlxsw_sp, &region->aregion.cregion, mlxsw_sp_acl_atcam_entry_del(mlxsw_sp, &region->aregion, &chunk->achunk,
&chunk->cchunk, &entry->aentry.centry); &entry->aentry);
} }
static int static int
......
...@@ -344,10 +344,12 @@ mlxsw_sp_acl_atcam_region_type_init(struct mlxsw_sp_acl_atcam_region *aregion) ...@@ -344,10 +344,12 @@ mlxsw_sp_acl_atcam_region_type_init(struct mlxsw_sp_acl_atcam_region *aregion)
aregion->ops = mlxsw_sp_acl_atcam_region_ops_arr[region_type]; aregion->ops = mlxsw_sp_acl_atcam_region_ops_arr[region_type];
} }
int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, int
struct mlxsw_sp_acl_atcam *atcam, mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_atcam_region *aregion, struct mlxsw_sp_acl_atcam *atcam,
struct mlxsw_sp_acl_tcam_region *region) struct mlxsw_sp_acl_atcam_region *aregion,
struct mlxsw_sp_acl_tcam_region *region,
const struct mlxsw_sp_acl_ctcam_region_ops *ops)
{ {
int err; int err;
...@@ -366,7 +368,7 @@ int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, ...@@ -366,7 +368,7 @@ int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
goto err_erp_region_init; goto err_erp_region_init;
err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &aregion->cregion, err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &aregion->cregion,
region); region, ops);
if (err) if (err)
goto err_ctcam_region_init; goto err_ctcam_region_init;
......
...@@ -98,6 +98,10 @@ mlxsw_sp_acl_ctcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, ...@@ -98,6 +98,10 @@ mlxsw_sp_acl_ctcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp,
mlxsw_afk_encode(afk, region->key_info, &rulei->values, key, mask, 0, mlxsw_afk_encode(afk, region->key_info, &rulei->values, key, mask, 0,
blocks_count - 1); blocks_count - 1);
err = cregion->ops->entry_insert(cregion, centry, mask);
if (err)
return err;
/* Only the first action set belongs here, the rest is in KVD */ /* Only the first action set belongs here, the rest is in KVD */
act_set = mlxsw_afa_block_first_set(rulei->act_block); act_set = mlxsw_afa_block_first_set(rulei->act_block);
mlxsw_reg_ptce2_flex_action_set_memcpy_to(ptce2_pl, act_set); mlxsw_reg_ptce2_flex_action_set_memcpy_to(ptce2_pl, act_set);
...@@ -116,6 +120,7 @@ mlxsw_sp_acl_ctcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp, ...@@ -116,6 +120,7 @@ mlxsw_sp_acl_ctcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp,
cregion->region->tcam_region_info, cregion->region->tcam_region_info,
centry->parman_item.index, 0); centry->parman_item.index, 0);
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl); mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl);
cregion->ops->entry_remove(cregion, centry);
} }
static int mlxsw_sp_acl_ctcam_region_parman_resize(void *priv, static int mlxsw_sp_acl_ctcam_region_parman_resize(void *priv,
...@@ -153,11 +158,14 @@ static const struct parman_ops mlxsw_sp_acl_ctcam_region_parman_ops = { ...@@ -153,11 +158,14 @@ static const struct parman_ops mlxsw_sp_acl_ctcam_region_parman_ops = {
.algo = PARMAN_ALGO_TYPE_LSORT, .algo = PARMAN_ALGO_TYPE_LSORT,
}; };
int mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp, int
struct mlxsw_sp_acl_ctcam_region *cregion, mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam_region *region) struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_tcam_region *region,
const struct mlxsw_sp_acl_ctcam_region_ops *ops)
{ {
cregion->region = region; cregion->region = region;
cregion->ops = ops;
cregion->parman = parman_create(&mlxsw_sp_acl_ctcam_region_parman_ops, cregion->parman = parman_create(&mlxsw_sp_acl_ctcam_region_parman_ops,
cregion); cregion);
if (!cregion->parman) if (!cregion->parman)
......
...@@ -1048,11 +1048,8 @@ mlxsw_sp_acl_erp_master_mask_init(struct mlxsw_sp_acl_atcam_region *aregion) ...@@ -1048,11 +1048,8 @@ mlxsw_sp_acl_erp_master_mask_init(struct mlxsw_sp_acl_atcam_region *aregion)
{ {
struct mlxsw_sp *mlxsw_sp = aregion->region->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = aregion->region->mlxsw_sp;
char percr_pl[MLXSW_REG_PERCR_LEN]; char percr_pl[MLXSW_REG_PERCR_LEN];
char *master_mask;
mlxsw_reg_percr_pack(percr_pl, aregion->region->id); mlxsw_reg_percr_pack(percr_pl, aregion->region->id);
master_mask = mlxsw_reg_percr_master_mask_data(percr_pl);
memset(master_mask, 0, MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(percr), percr_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(percr), percr_pl);
} }
...@@ -1062,7 +1059,7 @@ mlxsw_sp_acl_erp_region_param_init(struct mlxsw_sp_acl_atcam_region *aregion) ...@@ -1062,7 +1059,7 @@ mlxsw_sp_acl_erp_region_param_init(struct mlxsw_sp_acl_atcam_region *aregion)
struct mlxsw_sp *mlxsw_sp = aregion->region->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = aregion->region->mlxsw_sp;
char pererp_pl[MLXSW_REG_PERERP_LEN]; char pererp_pl[MLXSW_REG_PERERP_LEN];
mlxsw_reg_pererp_pack(pererp_pl, aregion->region->id, true, true, 0, mlxsw_reg_pererp_pack(pererp_pl, aregion->region->id, false, false, 0,
0, 0); 0, 0);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl);
} }
...@@ -1077,16 +1074,12 @@ int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion) ...@@ -1077,16 +1074,12 @@ int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion)
return PTR_ERR(erp_table); return PTR_ERR(erp_table);
aregion->erp_table = erp_table; aregion->erp_table = erp_table;
/* Initialize the region's master mask to all ones for C-TCAM /* Initialize the region's master mask to all zeroes */
* only mode
*/
err = mlxsw_sp_acl_erp_master_mask_init(aregion); err = mlxsw_sp_acl_erp_master_mask_init(aregion);
if (err) if (err)
goto err_erp_master_mask_init; goto err_erp_master_mask_init;
/* Initialize the region to use the eRP table and enable C-TCAM /* Initialize the region to not use the eRP table */
* lookup
*/
err = mlxsw_sp_acl_erp_region_param_init(aregion); err = mlxsw_sp_acl_erp_region_param_init(aregion);
if (err) if (err)
goto err_erp_region_param_init; goto err_erp_region_param_init;
......
...@@ -112,6 +112,7 @@ struct mlxsw_sp_acl_tcam_region { ...@@ -112,6 +112,7 @@ struct mlxsw_sp_acl_tcam_region {
struct mlxsw_sp_acl_ctcam_region { struct mlxsw_sp_acl_ctcam_region {
struct parman *parman; struct parman *parman;
const struct mlxsw_sp_acl_ctcam_region_ops *ops;
struct mlxsw_sp_acl_tcam_region *region; struct mlxsw_sp_acl_tcam_region *region;
}; };
...@@ -123,9 +124,19 @@ struct mlxsw_sp_acl_ctcam_entry { ...@@ -123,9 +124,19 @@ struct mlxsw_sp_acl_ctcam_entry {
struct parman_item parman_item; struct parman_item parman_item;
}; };
int mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ctcam_region_ops {
struct mlxsw_sp_acl_ctcam_region *cregion, int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_tcam_region *region); struct mlxsw_sp_acl_ctcam_entry *centry,
const char *mask);
void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_ctcam_entry *centry);
};
int
mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_tcam_region *region,
const struct mlxsw_sp_acl_ctcam_region_ops *ops);
void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion); void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion, void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
struct mlxsw_sp_acl_ctcam_chunk *cchunk, struct mlxsw_sp_acl_ctcam_chunk *cchunk,
...@@ -190,12 +201,26 @@ struct mlxsw_sp_acl_atcam_entry { ...@@ -190,12 +201,26 @@ struct mlxsw_sp_acl_atcam_entry {
struct mlxsw_sp_acl_erp *erp; struct mlxsw_sp_acl_erp *erp;
}; };
static inline struct mlxsw_sp_acl_atcam_region *
mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
{
return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
}
static inline struct mlxsw_sp_acl_atcam_entry *
mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
{
return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
}
int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
u16 region_id); u16 region_id);
int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, int
struct mlxsw_sp_acl_atcam *atcam, mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_atcam_region *aregion, struct mlxsw_sp_acl_atcam *atcam,
struct mlxsw_sp_acl_tcam_region *region); struct mlxsw_sp_acl_atcam_region *aregion,
struct mlxsw_sp_acl_tcam_region *region,
const struct mlxsw_sp_acl_ctcam_region_ops *ops);
void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion); void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion, void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
struct mlxsw_sp_acl_atcam_chunk *achunk, struct mlxsw_sp_acl_atcam_chunk *achunk,
......
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