File Index
Files and directories
Sign in
FILE

core_acl_flex_keys.h

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h C
  1/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
  2/* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
  3
  4#ifndef _MLXSW_CORE_ACL_FLEX_KEYS_H
  5#define _MLXSW_CORE_ACL_FLEX_KEYS_H
  6
  7#include <linux/types.h>
  8#include <linux/bitmap.h>
  9
 10#include "item.h"
 11
 12enum mlxsw_afk_element {
 13	MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
 14	MLXSW_AFK_ELEMENT_DMAC_32_47,
 15	MLXSW_AFK_ELEMENT_DMAC_0_31,
 16	MLXSW_AFK_ELEMENT_SMAC_32_47,
 17	MLXSW_AFK_ELEMENT_SMAC_0_31,
 18	MLXSW_AFK_ELEMENT_ETHERTYPE,
 19	MLXSW_AFK_ELEMENT_IP_PROTO,
 20	MLXSW_AFK_ELEMENT_SRC_IP_96_127,
 21	MLXSW_AFK_ELEMENT_SRC_IP_64_95,
 22	MLXSW_AFK_ELEMENT_SRC_IP_32_63,
 23	MLXSW_AFK_ELEMENT_SRC_IP_0_31,
 24	MLXSW_AFK_ELEMENT_DST_IP_96_127,
 25	MLXSW_AFK_ELEMENT_DST_IP_64_95,
 26	MLXSW_AFK_ELEMENT_DST_IP_32_63,
 27	MLXSW_AFK_ELEMENT_DST_IP_0_31,
 28	MLXSW_AFK_ELEMENT_DST_L4_PORT,
 29	MLXSW_AFK_ELEMENT_SRC_L4_PORT,
 30	MLXSW_AFK_ELEMENT_VID,
 31	MLXSW_AFK_ELEMENT_PCP,
 32	MLXSW_AFK_ELEMENT_TCP_FLAGS,
 33	MLXSW_AFK_ELEMENT_IP_TTL_,
 34	MLXSW_AFK_ELEMENT_IP_ECN,
 35	MLXSW_AFK_ELEMENT_IP_DSCP,
 36	MLXSW_AFK_ELEMENT_VIRT_ROUTER,
 37	MLXSW_AFK_ELEMENT_FDB_MISS,
 38	MLXSW_AFK_ELEMENT_L4_PORT_RANGE,
 39	MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_3,
 40	MLXSW_AFK_ELEMENT_VIRT_ROUTER_4_7,
 41	MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB,
 42	MLXSW_AFK_ELEMENT_MAX,
 43};
 44
 45enum mlxsw_afk_element_type {
 46	MLXSW_AFK_ELEMENT_TYPE_U32,
 47	MLXSW_AFK_ELEMENT_TYPE_BUF,
 48};
 49
 50struct mlxsw_afk_element_info {
 51	enum mlxsw_afk_element element; /* element ID */
 52	enum mlxsw_afk_element_type type;
 53	struct mlxsw_item item; /* element geometry in internal storage */
 54};
 55
 56#define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size)		\
 57	[MLXSW_AFK_ELEMENT_##_element] = {					\
 58		.element = MLXSW_AFK_ELEMENT_##_element,			\
 59		.type = _type,							\
 60		.item = {							\
 61			.offset = _offset,					\
 62			.shift = _shift,					\
 63			.size = {.bits = _size},				\
 64			.name = #_element,					\
 65		},								\
 66	}
 67
 68#define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size)		\
 69	MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32,			\
 70			       _element, _offset, _shift, _size)
 71
 72#define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size)			\
 73	MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF,			\
 74			       _element, _offset, 0, _size)
 75
 76#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x44
 77
 78struct mlxsw_afk_element_inst { /* element instance in actual block */
 79	enum mlxsw_afk_element element;
 80	enum mlxsw_afk_element_type type;
 81	struct mlxsw_item item; /* element geometry in block */
 82	int u32_key_diff; /* in case value needs to be adjusted before write
 83			   * this diff is here to handle that
 84			   */
 85	bool avoid_size_check;
 86};
 87
 88#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset,			\
 89			       _shift, _size, _u32_key_diff, _avoid_size_check)	\
 90	{									\
 91		.element = MLXSW_AFK_ELEMENT_##_element,			\
 92		.type = _type,							\
 93		.item = {							\
 94			.offset = _offset,					\
 95			.shift = _shift,					\
 96			.size = {.bits = _size},				\
 97			.name = #_element,					\
 98		},								\
 99		.u32_key_diff = _u32_key_diff,					\
100		.avoid_size_check = _avoid_size_check,				\
101	}
102
103#define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size)		\
104	MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,			\
105			       _element, _offset, _shift, _size, 0, false)
106
107#define MLXSW_AFK_ELEMENT_INST_EXT_U32(_element, _offset,			\
108				       _shift, _size, _key_diff,		\
109				       _avoid_size_check)			\
110	MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,			\
111			       _element, _offset, _shift, _size,		\
112			       _key_diff, _avoid_size_check)
113
114#define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size)			\
115	MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF,			\
116			       _element, _offset, 0, _size, 0, false)
117
118struct mlxsw_afk_block {
119	u16 encoding; /* block ID */
120	const struct mlxsw_afk_element_inst *instances;
121	unsigned int instances_count;
122	bool high_entropy;
123};
124
125#define MLXSW_AFK_BLOCK(_encoding, _instances)					\
126	{									\
127		.encoding = _encoding,						\
128		.instances = _instances,					\
129		.instances_count = ARRAY_SIZE(_instances),			\
130	}
131
132#define MLXSW_AFK_BLOCK_HIGH_ENTROPY(_encoding, _instances)			\
133	{									\
134		.encoding = _encoding,						\
135		.instances = _instances,					\
136		.instances_count = ARRAY_SIZE(_instances),			\
137		.high_entropy = true,						\
138	}
139
140struct mlxsw_afk_element_usage {
141	DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
142};
143
144#define mlxsw_afk_element_usage_for_each(element, elusage)			\
145	for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
146
147static inline void
148mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
149			    enum mlxsw_afk_element element)
150{
151	__set_bit(element, elusage->usage);
152}
153
154static inline void
155mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
156{
157	bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
158}
159
160static inline void
161mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
162			     const enum mlxsw_afk_element *elements,
163			     unsigned int elements_count)
164{
165	int i;
166
167	mlxsw_afk_element_usage_zero(elusage);
168	for (i = 0; i < elements_count; i++)
169		mlxsw_afk_element_usage_add(elusage, elements[i]);
170}
171
172static inline bool
173mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
174			       struct mlxsw_afk_element_usage *elusage_big)
175{
176	int i;
177
178	for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
179		if (test_bit(i, elusage_small->usage) &&
180		    !test_bit(i, elusage_big->usage))
181			return false;
182	return true;
183}
184
185struct mlxsw_afk;
186
187struct mlxsw_afk_ops {
188	const struct mlxsw_afk_block *blocks;
189	unsigned int blocks_count;
190	void (*encode_block)(char *output, int block_index, char *block);
191	void (*clear_block)(char *output, int block_index);
192};
193
194struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
195				   const struct mlxsw_afk_ops *ops);
196void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
197
198struct mlxsw_afk_key_info;
199
200struct mlxsw_afk_key_info *
201mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
202		       struct mlxsw_afk_element_usage *elusage);
203void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
204bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
205			       struct mlxsw_afk_element_usage *elusage);
206
207u16
208mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
209				      int block_index);
210unsigned int
211mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
212
213struct mlxsw_afk_element_values {
214	struct mlxsw_afk_element_usage elusage;
215	struct {
216		char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
217		char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
218	} storage;
219};
220
221void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
222			      enum mlxsw_afk_element element,
223			      u32 key_value, u32 mask_value);
224void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
225			      enum mlxsw_afk_element element,
226			      const char *key_value, const char *mask_value,
227			      unsigned int len);
228void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
229		      struct mlxsw_afk_key_info *key_info,
230		      struct mlxsw_afk_element_values *values,
231		      char *key, char *mask);
232void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
233		     int block_start, int block_end);
234
235#endif
~/ Read-only file preview.