1
2
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_8_10,
37 MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_7,
38 MLXSW_AFK_ELEMENT_MAX,
39};
40
41enum mlxsw_afk_element_type {
42 MLXSW_AFK_ELEMENT_TYPE_U32,
43 MLXSW_AFK_ELEMENT_TYPE_BUF,
44};
45
46struct mlxsw_afk_element_info {
47 enum mlxsw_afk_element element;
48 enum mlxsw_afk_element_type type;
49 struct mlxsw_item item;
50};
51
52#define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size) \
53 [MLXSW_AFK_ELEMENT_##_element] = { \
54 .element = MLXSW_AFK_ELEMENT_##_element, \
55 .type = _type, \
56 .item = { \
57 .offset = _offset, \
58 .shift = _shift, \
59 .size = {.bits = _size}, \
60 .name = #_element, \
61 }, \
62 }
63
64#define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size) \
65 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32, \
66 _element, _offset, _shift, _size)
67
68#define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size) \
69 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF, \
70 _element, _offset, 0, _size)
71
72#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
73
74struct mlxsw_afk_element_inst {
75 enum mlxsw_afk_element element;
76 enum mlxsw_afk_element_type type;
77 struct mlxsw_item item;
78 int u32_key_diff;
79
80
81 bool avoid_size_check;
82};
83
84#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, \
85 _shift, _size, _u32_key_diff, _avoid_size_check) \
86 { \
87 .element = MLXSW_AFK_ELEMENT_##_element, \
88 .type = _type, \
89 .item = { \
90 .offset = _offset, \
91 .shift = _shift, \
92 .size = {.bits = _size}, \
93 .name = #_element, \
94 }, \
95 .u32_key_diff = _u32_key_diff, \
96 .avoid_size_check = _avoid_size_check, \
97 }
98
99#define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size) \
100 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \
101 _element, _offset, _shift, _size, 0, false)
102
103#define MLXSW_AFK_ELEMENT_INST_EXT_U32(_element, _offset, \
104 _shift, _size, _key_diff, \
105 _avoid_size_check) \
106 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \
107 _element, _offset, _shift, _size, \
108 _key_diff, _avoid_size_check)
109
110#define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size) \
111 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF, \
112 _element, _offset, 0, _size, 0, false)
113
114struct mlxsw_afk_block {
115 u16 encoding;
116 struct mlxsw_afk_element_inst *instances;
117 unsigned int instances_count;
118};
119
120#define MLXSW_AFK_BLOCK(_encoding, _instances) \
121 { \
122 .encoding = _encoding, \
123 .instances = _instances, \
124 .instances_count = ARRAY_SIZE(_instances), \
125 }
126
127struct mlxsw_afk_element_usage {
128 DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
129};
130
131#define mlxsw_afk_element_usage_for_each(element, elusage) \
132 for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
133
134static inline void
135mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
136 enum mlxsw_afk_element element)
137{
138 __set_bit(element, elusage->usage);
139}
140
141static inline void
142mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
143{
144 bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
145}
146
147static inline void
148mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
149 const enum mlxsw_afk_element *elements,
150 unsigned int elements_count)
151{
152 int i;
153
154 mlxsw_afk_element_usage_zero(elusage);
155 for (i = 0; i < elements_count; i++)
156 mlxsw_afk_element_usage_add(elusage, elements[i]);
157}
158
159static inline bool
160mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
161 struct mlxsw_afk_element_usage *elusage_big)
162{
163 int i;
164
165 for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
166 if (test_bit(i, elusage_small->usage) &&
167 !test_bit(i, elusage_big->usage))
168 return false;
169 return true;
170}
171
172struct mlxsw_afk;
173
174struct mlxsw_afk_ops {
175 const struct mlxsw_afk_block *blocks;
176 unsigned int blocks_count;
177 void (*encode_block)(char *output, int block_index, char *block);
178 void (*clear_block)(char *output, int block_index);
179};
180
181struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
182 const struct mlxsw_afk_ops *ops);
183void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
184
185struct mlxsw_afk_key_info;
186
187struct mlxsw_afk_key_info *
188mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
189 struct mlxsw_afk_element_usage *elusage);
190void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
191bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
192 struct mlxsw_afk_element_usage *elusage);
193
194u16
195mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
196 int block_index);
197unsigned int
198mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
199
200struct mlxsw_afk_element_values {
201 struct mlxsw_afk_element_usage elusage;
202 struct {
203 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
204 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
205 } storage;
206};
207
208void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
209 enum mlxsw_afk_element element,
210 u32 key_value, u32 mask_value);
211void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
212 enum mlxsw_afk_element element,
213 const char *key_value, const char *mask_value,
214 unsigned int len);
215void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
216 struct mlxsw_afk_key_info *key_info,
217 struct mlxsw_afk_element_values *values,
218 char *key, char *mask);
219void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
220 int block_start, int block_end);
221
222#endif
223