diff mbox

[RESEND,net-next,mlxsw,14/18] mlxsw: spectrum_acl: Add A-TCAM region initialization

Message ID 20180717153657.16324-15-idosch@mellanox.com (mailing list archive)
State Changes Requested
Delegated to: Ido Schimmel
Headers show

Commit Message

Ido Schimmel July 17, 2018, 3:36 p.m. UTC
Before we start using the A-TCAM we need to make sure the region is
properly initialized.

This includes the setting of its type (which affects the size of its eRP
table, for example) and its registration with the eRP core.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c   | 18 ++++++--
 .../ethernet/mellanox/mlxsw/spectrum_acl_atcam.c   | 52 +++++++++++-----------
 .../ethernet/mellanox/mlxsw/spectrum_acl_tcam.h    |  2 +
 3 files changed, 43 insertions(+), 29 deletions(-)
diff mbox

Patch

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c
index 1aa80a4f37e2..c2d52d6fe312 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c
@@ -139,12 +139,21 @@  mlxsw_sp2_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv,
 
 	region->region = _region;
 
-	err = mlxsw_sp_acl_atcam_region_init(mlxsw_sp, &tcam->atcam, _region);
+	err = mlxsw_sp_acl_atcam_region_init(mlxsw_sp, &tcam->atcam,
+					     &region->aregion, _region);
 	if (err)
 		return err;
-	return mlxsw_sp_acl_ctcam_region_init(mlxsw_sp,
-					      &region->aregion.cregion,
-					      _region);
+
+	err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &region->aregion.cregion,
+					     _region);
+	if (err)
+		goto err_ctcam_region_init;
+
+	return 0;
+
+err_ctcam_region_init:
+	mlxsw_sp_acl_atcam_region_fini(&region->aregion);
+	return err;
 }
 
 static void
@@ -153,6 +162,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(&region->aregion.cregion);
+	mlxsw_sp_acl_atcam_region_fini(&region->aregion);
 }
 
 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 03f0ac646a21..037f1af1c72d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
@@ -57,42 +57,44 @@  int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(perar), perar_pl);
 }
 
-static int mlxsw_sp_acl_atcam_region_param_init(struct mlxsw_sp *mlxsw_sp,
-						u16 region_id)
+static void
+mlxsw_sp_acl_atcam_region_type_init(struct mlxsw_sp_acl_atcam_region *aregion)
 {
-	char percr_pl[MLXSW_REG_PERCR_LEN];
+	struct mlxsw_sp_acl_tcam_region *region = aregion->region;
+	enum mlxsw_sp_acl_atcam_region_type region_type;
+	unsigned int blocks_count;
 
-	mlxsw_reg_percr_pack(percr_pl, region_id);
-	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(percr), percr_pl);
-}
-
-static int
-mlxsw_sp_acl_atcam_region_erp_init(struct mlxsw_sp *mlxsw_sp,
-				   u16 region_id)
-{
-	char pererp_pl[MLXSW_REG_PERERP_LEN];
+	/* We already know the blocks count can not exceed the maximum
+	 * blocks count.
+	 */
+	blocks_count = mlxsw_afk_key_info_blocks_count_get(region->key_info);
+	if (blocks_count <= 2)
+		region_type = MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB;
+	else if (blocks_count <= 4)
+		region_type = MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB;
+	else if (blocks_count <= 8)
+		region_type = MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB;
+	else
+		region_type = MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB;
 
-	mlxsw_reg_pererp_pack(pererp_pl, region_id, true, true, 0, 0, 0);
-	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl);
+	aregion->type = 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 err;
+	aregion->region = region;
+	aregion->atcam = atcam;
+	mlxsw_sp_acl_atcam_region_type_init(aregion);
 
-	err = mlxsw_sp_acl_atcam_region_associate(mlxsw_sp, region->id);
-	if (err)
-		return err;
-	err = mlxsw_sp_acl_atcam_region_param_init(mlxsw_sp, region->id);
-	if (err)
-		return err;
-	err = mlxsw_sp_acl_atcam_region_erp_init(mlxsw_sp, region->id);
-	if (err)
-		return err;
+	return mlxsw_sp_acl_erp_region_init(aregion);
+}
 
-	return 0;
+void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion)
+{
+	mlxsw_sp_acl_erp_region_fini(aregion);
 }
 
 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
index 99d44ac3acd2..51f7e2327603 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
@@ -173,7 +173,9 @@  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);
+void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
 			    struct mlxsw_sp_acl_atcam *atcam);
 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,