Commit 4e86889b authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-ERP-sharing-multiple-masks'



Ido Schimmel says:

====================
mlxsw: spectrum: acl: Introduce ERP sharing by multiple masks

Jiri says:

The Spectrum-2 hardware has limitation number of ERPs per-region. In
order to accommodate more masks than number of ERPs, the hardware
supports to insert rules with delta bits. By that, the rules with masks
that differ in up-to 8 consecutive bits can share the same ERP.

Patches 1 and 2 fix couple of issues that would appear in existing
selftests after adding delta support

Patch 3 introduces a generic object aggregation library. Now it is
static, but it will get extended for recalculation of aggregations in
the future in order to reach more optimal aggregation.

Patch 4 just simply converts existing ERP code to use the objagg library
instead of a rhashtable.

Patches 5-9 do more or less small changes to prepare ground for the last
patch.

Patch 10 fills-up delta callbacks of objagg library and utilizes the
delta bits for rule insertion.

The last patch adds selftest to test the mlxsw Spectrum-2 delta flows.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6ab6dfa6 3b423271
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -10679,6 +10679,14 @@ L: linux-nfc@lists.01.org (moderated for non-subscribers)
S:	Supported
F:	drivers/nfc/nxp-nci

OBJAGG
M:	Jiri Pirko <jiri@mellanox.com>
L:	netdev@vger.kernel.org
S:	Supported
F:	lib/objagg.c
F:	lib/test_objagg.c
F:	include/linux/objagg.h

OBJTOOL
M:	Josh Poimboeuf <jpoimboe@redhat.com>
M:	Peter Zijlstra <peterz@infradead.org>
+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ config MLXSW_SPECTRUM
	depends on IPV6_GRE || IPV6_GRE=n
	select GENERIC_ALLOCATOR
	select PARMAN
	select OBJAGG
	select MLXFW
	default m
	---help---
+16 −6
Original line number Diff line number Diff line
@@ -426,15 +426,17 @@ mlxsw_sp_afk_encode_one(const struct mlxsw_afk_element_inst *elinst,
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, int block_start, int block_end)
		      char *key, char *mask)
{
	unsigned int blocks_count =
			mlxsw_afk_key_info_blocks_count_get(key_info);
	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, i;

	for (i = block_start; i <= block_end; i++) {
	for (i = 0; i < 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);

@@ -451,10 +453,18 @@ void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
						values->storage.mask);
		}

		if (key)
			mlxsw_afk->ops->encode_block(block_key, i, key);
		if (mask)
			mlxsw_afk->ops->encode_block(block_mask, i, mask);
		mlxsw_afk->ops->encode_block(key, i, block_key);
		mlxsw_afk->ops->encode_block(mask, i, block_mask);
	}
}
EXPORT_SYMBOL(mlxsw_afk_encode);

void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
		     int block_start, int block_end)
{
	int i;

	for (i = block_start; i <= block_end; i++)
		mlxsw_afk->ops->clear_block(key, i);
}
EXPORT_SYMBOL(mlxsw_afk_clear);
+5 −2
Original line number Diff line number Diff line
@@ -188,7 +188,8 @@ struct mlxsw_afk;
struct mlxsw_afk_ops {
	const struct mlxsw_afk_block *blocks;
	unsigned int blocks_count;
	void (*encode_block)(char *block, int block_index, char *output);
	void (*encode_block)(char *output, int block_index, char *block);
	void (*clear_block)(char *output, int block_index);
};

struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
@@ -228,6 +229,8 @@ void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
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, int block_start, int block_end);
		      char *key, char *mask);
void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
		     int block_start, int block_end);

#endif
+6 −2
Original line number Diff line number Diff line
@@ -2834,8 +2834,9 @@ static inline void mlxsw_reg_ptce3_pack(char *payload, bool valid,
					u32 priority,
					const char *tcam_region_info,
					const char *key, u8 erp_id,
					bool large_exists, u32 lkey_id,
					u32 action_pointer)
					u16 delta_start, u8 delta_mask,
					u8 delta_value, bool large_exists,
					u32 lkey_id, u32 action_pointer)
{
	MLXSW_REG_ZERO(ptce3, payload);
	mlxsw_reg_ptce3_v_set(payload, valid);
@@ -2844,6 +2845,9 @@ static inline void mlxsw_reg_ptce3_pack(char *payload, bool valid,
	mlxsw_reg_ptce3_tcam_region_info_memcpy_to(payload, tcam_region_info);
	mlxsw_reg_ptce3_flex2_key_blocks_memcpy_to(payload, key);
	mlxsw_reg_ptce3_erp_id_set(payload, erp_id);
	mlxsw_reg_ptce3_delta_start_set(payload, delta_start);
	mlxsw_reg_ptce3_delta_mask_set(payload, delta_mask);
	mlxsw_reg_ptce3_delta_value_set(payload, delta_value);
	mlxsw_reg_ptce3_large_exists_set(payload, large_exists);
	mlxsw_reg_ptce3_large_entry_key_id_set(payload, lkey_id);
	mlxsw_reg_ptce3_action_pointer_set(payload, action_pointer);
Loading