diff mbox

[net-next/mlxsw,internal,v2,12/15] mlxsw: spectrum_acl: Prepare for Spectrum-2 block encoding

Message ID 20180627143005.2016-13-jiri@resnulli.us (mailing list archive)
State Accepted
Delegated to: Ido Schimmel
Headers show

Commit Message

Jiri Pirko June 27, 2018, 2:30 p.m. UTC
From: Ido Schimmel <idosch@mellanox.com>

In Spectrum the key (and mask) block layout is very straight forward and
every block is 16 bytes aligned.

However, in Spectrum-2 the blocks are not even byte aligned, which makes
it difficult to encode them using current method.

Instead, first encode each block and then encode the block in the
general blocks layout.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v1->v2:
- s/Spectrum2/Spectrum-2/
---
 .../ethernet/mellanox/mlxsw/core_acl_flex_keys.c   | 70 ++++++++++++++++++----
 .../ethernet/mellanox/mlxsw/core_acl_flex_keys.h   |  3 +-
 .../mellanox/mlxsw/spectrum_acl_flex_keys.c        | 46 ++------------
 3 files changed, 66 insertions(+), 53 deletions(-)
diff mbox

Patch

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c
index bf645215f514..5f8485c7640e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c
@@ -416,24 +416,74 @@  void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
 }
 EXPORT_SYMBOL(mlxsw_afk_values_add_buf);
 
+static void mlxsw_sp_afk_encode_u32(const struct mlxsw_item *storage_item,
+				    const struct mlxsw_item *output_item,
+				    char *storage, char *output)
+{
+	u32 value;
+
+	value = __mlxsw_item_get32(storage, storage_item, 0);
+	__mlxsw_item_set32(output, output_item, 0, value);
+}
+
+static void mlxsw_sp_afk_encode_buf(const struct mlxsw_item *storage_item,
+				    const struct mlxsw_item *output_item,
+				    char *storage, char *output)
+{
+	char *storage_data = __mlxsw_item_data(storage, storage_item, 0);
+	char *output_data = __mlxsw_item_data(output, output_item, 0);
+	size_t len = output_item->size.bytes;
+
+	memcpy(output_data, storage_data, len);
+}
+
+static void
+mlxsw_sp_afk_encode_one(const struct mlxsw_afk_element_inst *elinst,
+			char *output, char *storage)
+{
+	const struct mlxsw_item *storage_item = &elinst->info->item;
+	const struct mlxsw_item *output_item = &elinst->item;
+
+	if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_U32)
+		mlxsw_sp_afk_encode_u32(storage_item, output_item,
+					storage, output);
+	else if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_BUF)
+		mlxsw_sp_afk_encode_buf(storage_item, output_item,
+					storage, output);
+}
+
+#define MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE 16
+
 void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
 		      struct mlxsw_afk_key_info *key_info,
 		      struct mlxsw_afk_element_values *values,
 		      char *key, char *mask)
 {
+	char block_mask[MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE];
+	char block_key[MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE];
 	const struct mlxsw_afk_element_inst *elinst;
 	enum mlxsw_afk_element element;
-	int block_index;
+	int block_index, i;
+
+	for (i = 0; i < key_info->blocks_count; i++) {
+		memset(block_key, 0, MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE);
+		memset(block_mask, 0, MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE);
+
+		mlxsw_afk_element_usage_for_each(element, &values->elusage) {
+			elinst = mlxsw_afk_key_info_elinst_get(key_info,
+							       element,
+							       &block_index);
+			if (!elinst || block_index != i)
+				continue;
+
+			mlxsw_sp_afk_encode_one(elinst, block_key,
+						values->storage.key);
+			mlxsw_sp_afk_encode_one(elinst, block_mask,
+						values->storage.mask);
+		}
 
-	mlxsw_afk_element_usage_for_each(element, &values->elusage) {
-		elinst = mlxsw_afk_key_info_elinst_get(key_info, element,
-						       &block_index);
-		if (!elinst)
-			continue;
-		mlxsw_afk->ops->encode_one(elinst, block_index,
-					   values->storage.key, key);
-		mlxsw_afk->ops->encode_one(elinst, block_index,
-					   values->storage.mask, mask);
+		mlxsw_afk->ops->encode_block(block_key, i, key);
+		mlxsw_afk->ops->encode_block(block_mask, i, mask);
 	}
 }
 EXPORT_SYMBOL(mlxsw_afk_encode);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
index 441636cd13d8..2ffde915349b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
@@ -219,8 +219,7 @@  struct mlxsw_afk;
 struct mlxsw_afk_ops {
 	const struct mlxsw_afk_block *blocks;
 	unsigned int blocks_count;
-	void (*encode_one)(const struct mlxsw_afk_element_inst *elinst,
-			   int block_index, char *storage, char *output);
+	void (*encode_block)(char *block, int block_index, char *output);
 };
 
 struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c
index fe46338f0087..21be0987a93a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c
@@ -127,50 +127,21 @@  static const struct mlxsw_afk_block mlxsw_sp1_afk_blocks[] = {
 	MLXSW_AFK_BLOCK(0xB0, mlxsw_sp_afk_element_info_packet_type),
 };
 
-static void mlxsw_sp1_afk_encode_u32(const struct mlxsw_item *storage_item,
-				     const struct mlxsw_item *output_item,
-				     char *storage, char *output_indexed)
-{
-	u32 value;
-
-	value = __mlxsw_item_get32(storage, storage_item, 0);
-	__mlxsw_item_set32(output_indexed, output_item, 0, value);
-}
-
-static void mlxsw_sp1_afk_encode_buf(const struct mlxsw_item *storage_item,
-				     const struct mlxsw_item *output_item,
-				     char *storage, char *output_indexed)
-{
-	char *storage_data = __mlxsw_item_data(storage, storage_item, 0);
-	char *output_data = __mlxsw_item_data(output_indexed, output_item, 0);
-	size_t len = output_item->size.bytes;
-
-	memcpy(output_data, storage_data, len);
-}
-
 #define MLXSW_SP1_AFK_KEY_BLOCK_SIZE 16
 
-static void
-mlxsw_sp1_afk_encode_one(const struct mlxsw_afk_element_inst *elinst,
-			 int block_index, char *storage, char *output)
+static void mlxsw_sp1_afk_encode_block(char *block, int block_index,
+				       char *output)
 {
 	unsigned int offset = block_index * MLXSW_SP1_AFK_KEY_BLOCK_SIZE;
 	char *output_indexed = output + offset;
-	const struct mlxsw_item *storage_item = &elinst->info->item;
-	const struct mlxsw_item *output_item = &elinst->item;
-
-	if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_U32)
-		mlxsw_sp1_afk_encode_u32(storage_item, output_item,
-					 storage, output_indexed);
-	else if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_BUF)
-		mlxsw_sp1_afk_encode_buf(storage_item, output_item,
-					 storage, output_indexed);
+
+	memcpy(output_indexed, block, MLXSW_SP1_AFK_KEY_BLOCK_SIZE);
 }
 
 const struct mlxsw_afk_ops mlxsw_sp1_afk_ops = {
 	.blocks		= mlxsw_sp1_afk_blocks,
 	.blocks_count	= ARRAY_SIZE(mlxsw_sp1_afk_blocks),
-	.encode_one	= mlxsw_sp1_afk_encode_one,
+	.encode_block	= mlxsw_sp1_afk_encode_block,
 };
 
 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_0[] = {
@@ -271,14 +242,7 @@  static const struct mlxsw_afk_block mlxsw_sp2_afk_blocks[] = {
 	MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2),
 };
 
-static void
-mlxsw_sp2_afk_encode_one(const struct mlxsw_afk_element_inst *elinst,
-			 int block_index, char *storage, char *output)
-{
-}
-
 const struct mlxsw_afk_ops mlxsw_sp2_afk_ops = {
 	.blocks		= mlxsw_sp2_afk_blocks,
 	.blocks_count	= ARRAY_SIZE(mlxsw_sp2_afk_blocks),
-	.encode_one	= mlxsw_sp2_afk_encode_one,
 };