Blob Blame History Raw
From: Ido Schimmel <idosch@mellanox.com>
Date: Wed, 25 Jul 2018 09:24:03 +0300
Subject: mlxsw: spectrum_acl: Add A-TCAM region initialization
Patch-mainline: v4.19-rc1
Git-commit: 6d240650bcfdba2860ab2691b5fd4352105d95a0
References: bsc#1112374

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>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c |   57 ++++++++-------
 1 file changed, 34 insertions(+), 23 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
@@ -57,23 +57,27 @@ int mlxsw_sp_acl_atcam_region_associate(
 	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;
+
+	/* 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_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];
-
-	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,
@@ -83,22 +87,29 @@ int mlxsw_sp_acl_atcam_region_init(struc
 {
 	int err;
 
-	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);
+	aregion->region = region;
+	aregion->atcam = atcam;
+	mlxsw_sp_acl_atcam_region_type_init(aregion);
+
+	err = mlxsw_sp_acl_erp_region_init(aregion);
 	if (err)
 		return err;
-	err = mlxsw_sp_acl_atcam_region_erp_init(mlxsw_sp, region->id);
+	err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &aregion->cregion,
+					     region);
 	if (err)
-		return err;
-	return mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &aregion->cregion,
-					      region);
+		goto err_ctcam_region_init;
+
+	return 0;
+
+err_ctcam_region_init:
+	mlxsw_sp_acl_erp_region_fini(aregion);
+	return err;
 }
 
 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion)
 {
 	mlxsw_sp_acl_ctcam_region_fini(&aregion->cregion);
+	mlxsw_sp_acl_erp_region_fini(aregion);
 }
 
 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,