diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c | 82 |
1 files changed, 65 insertions, 17 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c index d7f1fb35ea2a..22c876496379 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c @@ -39,23 +39,64 @@ #include "core_acl_flex_actions.h" struct mlxsw_sp2_acl_tcam { + struct mlxsw_sp_acl_atcam atcam; u32 kvdl_index; unsigned int kvdl_count; }; struct mlxsw_sp2_acl_tcam_region { - struct mlxsw_sp_acl_ctcam_region cregion; + struct mlxsw_sp_acl_atcam_region aregion; + struct mlxsw_sp_acl_tcam_region *region; }; 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_sp_acl_ctcam_entry centry; + struct mlxsw_sp_acl_atcam_entry aentry; 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, struct mlxsw_sp_acl_tcam *_tcam) { @@ -99,9 +140,14 @@ static int mlxsw_sp2_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv, if (err) goto err_pgcr_write; + err = mlxsw_sp_acl_atcam_init(mlxsw_sp, &tcam->atcam); + if (err) + goto err_atcam_init; + mlxsw_afa_block_destroy(afa_block); return 0; +err_atcam_init: err_pgcr_write: err_pefa_write: err_afa_block_continue: @@ -116,22 +162,24 @@ static void mlxsw_sp2_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, void *priv) { struct mlxsw_sp2_acl_tcam *tcam = priv; + mlxsw_sp_acl_atcam_fini(mlxsw_sp, &tcam->atcam); mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ACTSET, tcam->kvdl_count, tcam->kvdl_index); } static int mlxsw_sp2_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv, + void *tcam_priv, struct mlxsw_sp_acl_tcam_region *_region) { struct mlxsw_sp2_acl_tcam_region *region = region_priv; - int err; + struct mlxsw_sp2_acl_tcam *tcam = tcam_priv; - err = mlxsw_sp_acl_atcam_region_init(mlxsw_sp, _region); - if (err) - return err; - return mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, ®ion->cregion, - _region); + region->region = _region; + + return mlxsw_sp_acl_atcam_region_init(mlxsw_sp, &tcam->atcam, + ®ion->aregion, _region, + &mlxsw_sp2_acl_ctcam_region_ops); } static void @@ -139,7 +187,7 @@ mlxsw_sp2_acl_tcam_region_fini(struct mlxsw_sp *mlxsw_sp, void *region_priv) { struct mlxsw_sp2_acl_tcam_region *region = region_priv; - mlxsw_sp_acl_ctcam_region_fini(®ion->cregion); + mlxsw_sp_acl_atcam_region_fini(®ion->aregion); } static int @@ -155,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_chunk *chunk = chunk_priv; - mlxsw_sp_acl_ctcam_chunk_init(®ion->cregion, &chunk->cchunk, + mlxsw_sp_acl_atcam_chunk_init(®ion->aregion, &chunk->achunk, priority); } @@ -163,7 +211,7 @@ static void mlxsw_sp2_acl_tcam_chunk_fini(void *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, @@ -176,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; entry->act_block = rulei->act_block; - return mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, ®ion->cregion, - &chunk->cchunk, &entry->centry, - rulei, true); + return mlxsw_sp_acl_atcam_entry_add(mlxsw_sp, ®ion->aregion, + &chunk->achunk, &entry->aentry, + rulei); } static void mlxsw_sp2_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp, @@ -189,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_entry *entry = entry_priv; - mlxsw_sp_acl_ctcam_entry_del(mlxsw_sp, ®ion->cregion, - &chunk->cchunk, &entry->centry); + mlxsw_sp_acl_atcam_entry_del(mlxsw_sp, ®ion->aregion, &chunk->achunk, + &entry->aentry); } static int |