diff options
author | Ido Schimmel <idosch@mellanox.com> | 2018-07-25 09:24:06 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-26 02:46:02 +0300 |
commit | a0a777b9409fdb61ec4a752f8f9e88f5916e0a70 (patch) | |
tree | 88fdeafe4263fa22f99adf0d774fea7a721cb033 | |
parent | a8758b67bf37ceb50e5b8c2b9138231c76461d20 (diff) | |
download | linux-a0a777b9409fdb61ec4a752f8f9e88f5916e0a70.tar.xz |
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: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
7 files changed, 124 insertions, 36 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 5acef249e776..fd2e3dd166d2 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -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_ctcam_ignore_prune_set(payload, false); mlxsw_reg_percr_bf_bypass_set(payload, true); - memset(payload + 0x20, 0xff, 96); } /* PERERP - Policy-Engine Region eRP Register diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c index 926483434e99..5c8956573632 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c @@ -58,6 +58,26 @@ struct mlxsw_sp1_acl_tcam_entry { 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, struct mlxsw_sp_acl_tcam *tcam) { @@ -129,7 +149,8 @@ mlxsw_sp1_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv, int err; err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, ®ion->cregion, - _region); + _region, + &mlxsw_sp1_acl_ctcam_region_ops); if (err) return err; err = mlxsw_sp1_acl_ctcam_region_catchall_add(mlxsw_sp, region); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c index aef366148cc3..22c876496379 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c @@ -50,7 +50,7 @@ struct mlxsw_sp2_acl_tcam_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 { @@ -58,6 +58,45 @@ struct mlxsw_sp2_acl_tcam_entry { 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) { @@ -139,7 +178,8 @@ mlxsw_sp2_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv, region->region = _region; return mlxsw_sp_acl_atcam_region_init(mlxsw_sp, &tcam->atcam, - ®ion->aregion, _region); + ®ion->aregion, _region, + &mlxsw_sp2_acl_ctcam_region_ops); } static void @@ -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_chunk *chunk = chunk_priv; - mlxsw_sp_acl_ctcam_chunk_init(®ion->aregion.cregion, &chunk->cchunk, + mlxsw_sp_acl_atcam_chunk_init(®ion->aregion, &chunk->achunk, priority); } @@ -171,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, @@ -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; entry->act_block = rulei->act_block; - return mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, ®ion->aregion.cregion, - &chunk->cchunk, - &entry->aentry.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, @@ -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_entry *entry = entry_priv; - mlxsw_sp_acl_ctcam_entry_del(mlxsw_sp, ®ion->aregion.cregion, - &chunk->cchunk, &entry->aentry.centry); + mlxsw_sp_acl_atcam_entry_del(mlxsw_sp, ®ion->aregion, &chunk->achunk, + &entry->aentry); } static int diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c index d551f0431248..3a05e0b3f730 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c @@ -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]; } -int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_atcam *atcam, - struct mlxsw_sp_acl_atcam_region *aregion, - struct mlxsw_sp_acl_tcam_region *region) +int +mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_atcam *atcam, + 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; @@ -366,7 +368,7 @@ int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, if (err) goto err_erp_region_init; err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &aregion->cregion, - region); + region, ops); if (err) goto err_ctcam_region_init; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_ctcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_ctcam.c index 7ff31247cac7..7440a1189250 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_ctcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_ctcam.c @@ -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, 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 */ act_set = mlxsw_afa_block_first_set(rulei->act_block); 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, cregion->region->tcam_region_info, centry->parman_item.index, 0); 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, @@ -153,11 +158,14 @@ static const struct parman_ops mlxsw_sp_acl_ctcam_region_parman_ops = { .algo = PARMAN_ALGO_TYPE_LSORT, }; -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) +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) { cregion->region = region; + cregion->ops = ops; cregion->parman = parman_create(&mlxsw_sp_acl_ctcam_region_parman_ops, cregion); if (!cregion->parman) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c index bb07723a0577..463590bbb348 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c @@ -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; char percr_pl[MLXSW_REG_PERCR_LEN]; - char *master_mask; 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); } @@ -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; 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); 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) return PTR_ERR(erp_table); aregion->erp_table = erp_table; - /* Initialize the region's master mask to all ones for C-TCAM - * only mode - */ + /* Initialize the region's master mask to all zeroes */ err = mlxsw_sp_acl_erp_master_mask_init(aregion); if (err) goto err_erp_master_mask_init; - /* Initialize the region to use the eRP table and enable C-TCAM - * lookup - */ + /* Initialize the region to not use the eRP table */ err = mlxsw_sp_acl_erp_region_param_init(aregion); if (err) goto err_erp_region_param_init; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h index fb6f9a521ddb..881ade760ace 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h @@ -112,6 +112,7 @@ struct mlxsw_sp_acl_tcam_region { struct mlxsw_sp_acl_ctcam_region { struct parman *parman; + const struct mlxsw_sp_acl_ctcam_region_ops *ops; struct mlxsw_sp_acl_tcam_region *region; }; @@ -123,9 +124,19 @@ struct mlxsw_sp_acl_ctcam_entry { struct parman_item parman_item; }; -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); +struct mlxsw_sp_acl_ctcam_region_ops { + int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion, + 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_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion, struct mlxsw_sp_acl_ctcam_chunk *cchunk, @@ -190,12 +201,26 @@ struct mlxsw_sp_acl_atcam_entry { 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, u16 region_id); -int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_atcam *atcam, - struct mlxsw_sp_acl_atcam_region *aregion, - struct mlxsw_sp_acl_tcam_region *region); +int +mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_atcam *atcam, + 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_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion, struct mlxsw_sp_acl_atcam_chunk *achunk, |