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 <ido...@mellanox.com>
Reviewed-by: Jiri Pirko <j...@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h     |  1 -
 .../mellanox/mlxsw/spectrum1_acl_tcam.c       | 23 +++++++-
 .../mellanox/mlxsw/spectrum2_acl_tcam.c       | 58 ++++++++++++++++---
 .../mellanox/mlxsw/spectrum_acl_atcam.c       | 12 ++--
 .../mellanox/mlxsw/spectrum_acl_ctcam.c       | 14 ++++-
 .../mellanox/mlxsw/spectrum_acl_erp.c         | 13 +----
 .../mellanox/mlxsw/spectrum_acl_tcam.h        | 39 ++++++++++---
 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, &region->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,
-                                             &region->aregion, _region);
+                                             &region->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(&region->aregion.cregion, &chunk->cchunk,
+       mlxsw_sp_acl_atcam_chunk_init(&region->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, &region->aregion.cregion,
-                                           &chunk->cchunk,
-                                           &entry->aentry.centry, rulei, true);
+       return mlxsw_sp_acl_atcam_entry_add(mlxsw_sp, &region->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, &region->aregion.cregion,
-                                    &chunk->cchunk, &entry->aentry.centry);
+       mlxsw_sp_acl_atcam_entry_del(mlxsw_sp, &region->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,
-- 
2.17.1

Reply via email to