1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
4 #ifndef _MLXSW_CORE_ACL_FLEX_KEYS_H
5 #define _MLXSW_CORE_ACL_FLEX_KEYS_H
7 #include <linux/types.h>
8 #include <linux/bitmap.h>
12 enum 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_MSB,
37 MLXSW_AFK_ELEMENT_VIRT_ROUTER_LSB,
38 MLXSW_AFK_ELEMENT_FDB_MISS,
39 MLXSW_AFK_ELEMENT_MAX,
42 enum mlxsw_afk_element_type {
43 MLXSW_AFK_ELEMENT_TYPE_U32,
44 MLXSW_AFK_ELEMENT_TYPE_BUF,
47 struct mlxsw_afk_element_info {
48 enum mlxsw_afk_element element; /* element ID */
49 enum mlxsw_afk_element_type type;
50 struct mlxsw_item item; /* element geometry in internal storage */
53 #define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size) \
54 [MLXSW_AFK_ELEMENT_##_element] = { \
55 .element = MLXSW_AFK_ELEMENT_##_element, \
60 .size = {.bits = _size}, \
65 #define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size) \
66 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32, \
67 _element, _offset, _shift, _size)
69 #define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size) \
70 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF, \
71 _element, _offset, 0, _size)
73 #define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x44
75 struct mlxsw_afk_element_inst { /* element instance in actual block */
76 enum mlxsw_afk_element element;
77 enum mlxsw_afk_element_type type;
78 struct mlxsw_item item; /* element geometry in block */
79 int u32_key_diff; /* in case value needs to be adjusted before write
80 * this diff is here to handle that
82 bool avoid_size_check;
85 #define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, \
86 _shift, _size, _u32_key_diff, _avoid_size_check) \
88 .element = MLXSW_AFK_ELEMENT_##_element, \
93 .size = {.bits = _size}, \
96 .u32_key_diff = _u32_key_diff, \
97 .avoid_size_check = _avoid_size_check, \
100 #define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size) \
101 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \
102 _element, _offset, _shift, _size, 0, false)
104 #define MLXSW_AFK_ELEMENT_INST_EXT_U32(_element, _offset, \
105 _shift, _size, _key_diff, \
107 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \
108 _element, _offset, _shift, _size, \
109 _key_diff, _avoid_size_check)
111 #define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size) \
112 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF, \
113 _element, _offset, 0, _size, 0, false)
115 struct mlxsw_afk_block {
116 u16 encoding; /* block ID */
117 struct mlxsw_afk_element_inst *instances;
118 unsigned int instances_count;
121 #define MLXSW_AFK_BLOCK(_encoding, _instances) \
123 .encoding = _encoding, \
124 .instances = _instances, \
125 .instances_count = ARRAY_SIZE(_instances), \
128 struct mlxsw_afk_element_usage {
129 DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
132 #define mlxsw_afk_element_usage_for_each(element, elusage) \
133 for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
136 mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
137 enum mlxsw_afk_element element)
139 __set_bit(element, elusage->usage);
143 mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
145 bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
149 mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
150 const enum mlxsw_afk_element *elements,
151 unsigned int elements_count)
155 mlxsw_afk_element_usage_zero(elusage);
156 for (i = 0; i < elements_count; i++)
157 mlxsw_afk_element_usage_add(elusage, elements[i]);
161 mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
162 struct mlxsw_afk_element_usage *elusage_big)
166 for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
167 if (test_bit(i, elusage_small->usage) &&
168 !test_bit(i, elusage_big->usage))
175 struct mlxsw_afk_ops {
176 const struct mlxsw_afk_block *blocks;
177 unsigned int blocks_count;
178 void (*encode_block)(char *output, int block_index, char *block);
179 void (*clear_block)(char *output, int block_index);
182 struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
183 const struct mlxsw_afk_ops *ops);
184 void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
186 struct mlxsw_afk_key_info;
188 struct mlxsw_afk_key_info *
189 mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
190 struct mlxsw_afk_element_usage *elusage);
191 void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
192 bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
193 struct mlxsw_afk_element_usage *elusage);
196 mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
199 mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
201 struct mlxsw_afk_element_values {
202 struct mlxsw_afk_element_usage elusage;
204 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
205 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
209 void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
210 enum mlxsw_afk_element element,
211 u32 key_value, u32 mask_value);
212 void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
213 enum mlxsw_afk_element element,
214 const char *key_value, const char *mask_value,
216 void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
217 struct mlxsw_afk_key_info *key_info,
218 struct mlxsw_afk_element_values *values,
219 char *key, char *mask);
220 void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
221 int block_start, int block_end);