1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#ifndef _MLXSW_CORE_ACL_FLEX_KEYS_H
36#define _MLXSW_CORE_ACL_FLEX_KEYS_H
37
38#include <linux/types.h>
39#include <linux/bitmap.h>
40
41#include "item.h"
42
43enum mlxsw_afk_element {
44 MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
45 MLXSW_AFK_ELEMENT_DMAC,
46 MLXSW_AFK_ELEMENT_SMAC,
47 MLXSW_AFK_ELEMENT_ETHERTYPE,
48 MLXSW_AFK_ELEMENT_IP_PROTO,
49 MLXSW_AFK_ELEMENT_SRC_IP4,
50 MLXSW_AFK_ELEMENT_DST_IP4,
51 MLXSW_AFK_ELEMENT_SRC_IP6_HI,
52 MLXSW_AFK_ELEMENT_SRC_IP6_LO,
53 MLXSW_AFK_ELEMENT_DST_IP6_HI,
54 MLXSW_AFK_ELEMENT_DST_IP6_LO,
55 MLXSW_AFK_ELEMENT_DST_L4_PORT,
56 MLXSW_AFK_ELEMENT_SRC_L4_PORT,
57 MLXSW_AFK_ELEMENT_VID,
58 MLXSW_AFK_ELEMENT_PCP,
59 MLXSW_AFK_ELEMENT_TCP_FLAGS,
60 MLXSW_AFK_ELEMENT_IP_TTL_,
61 MLXSW_AFK_ELEMENT_IP_ECN,
62 MLXSW_AFK_ELEMENT_IP_DSCP,
63 MLXSW_AFK_ELEMENT_MAX,
64};
65
66enum mlxsw_afk_element_type {
67 MLXSW_AFK_ELEMENT_TYPE_U32,
68 MLXSW_AFK_ELEMENT_TYPE_BUF,
69};
70
71struct mlxsw_afk_element_info {
72 enum mlxsw_afk_element element;
73 enum mlxsw_afk_element_type type;
74 struct mlxsw_item item;
75};
76
77#define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size) \
78 [MLXSW_AFK_ELEMENT_##_element] = { \
79 .element = MLXSW_AFK_ELEMENT_##_element, \
80 .type = _type, \
81 .item = { \
82 .offset = _offset, \
83 .shift = _shift, \
84 .size = {.bits = _size}, \
85 .name = #_element, \
86 }, \
87 }
88
89#define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size) \
90 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32, \
91 _element, _offset, _shift, _size)
92
93#define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size) \
94 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF, \
95 _element, _offset, 0, _size)
96
97
98
99
100
101static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
102 MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 16),
103 MLXSW_AFK_ELEMENT_INFO_BUF(DMAC, 0x04, 6),
104 MLXSW_AFK_ELEMENT_INFO_BUF(SMAC, 0x0A, 6),
105 MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
106 MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
107 MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
108 MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
109 MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9),
110 MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
111 MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
112 MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
113 MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
114 MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
115 MLXSW_AFK_ELEMENT_INFO_U32(SRC_IP4, 0x20, 0, 32),
116 MLXSW_AFK_ELEMENT_INFO_U32(DST_IP4, 0x24, 0, 32),
117 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_HI, 0x20, 8),
118 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_LO, 0x28, 8),
119 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_HI, 0x30, 8),
120 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_LO, 0x38, 8),
121};
122
123#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
124
125struct mlxsw_afk_element_inst {
126 const struct mlxsw_afk_element_info *info;
127 enum mlxsw_afk_element_type type;
128 struct mlxsw_item item;
129};
130
131#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, _shift, _size) \
132 { \
133 .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
134 .type = _type, \
135 .item = { \
136 .offset = _offset, \
137 .shift = _shift, \
138 .size = {.bits = _size}, \
139 .name = #_element, \
140 }, \
141 }
142
143#define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size) \
144 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \
145 _element, _offset, _shift, _size)
146
147#define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size) \
148 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF, \
149 _element, _offset, 0, _size)
150
151struct mlxsw_afk_block {
152 u16 encoding;
153 struct mlxsw_afk_element_inst *instances;
154 unsigned int instances_count;
155};
156
157#define MLXSW_AFK_BLOCK(_encoding, _instances) \
158 { \
159 .encoding = _encoding, \
160 .instances = _instances, \
161 .instances_count = ARRAY_SIZE(_instances), \
162 }
163
164struct mlxsw_afk_element_usage {
165 DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
166};
167
168#define mlxsw_afk_element_usage_for_each(element, elusage) \
169 for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
170
171static inline void
172mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
173 enum mlxsw_afk_element element)
174{
175 __set_bit(element, elusage->usage);
176}
177
178static inline void
179mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
180{
181 bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
182}
183
184static inline void
185mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
186 const enum mlxsw_afk_element *elements,
187 unsigned int elements_count)
188{
189 int i;
190
191 mlxsw_afk_element_usage_zero(elusage);
192 for (i = 0; i < elements_count; i++)
193 mlxsw_afk_element_usage_add(elusage, elements[i]);
194}
195
196static inline bool
197mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
198 struct mlxsw_afk_element_usage *elusage_big)
199{
200 int i;
201
202 for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
203 if (test_bit(i, elusage_small->usage) &&
204 !test_bit(i, elusage_big->usage))
205 return false;
206 return true;
207}
208
209struct mlxsw_afk;
210
211struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
212 const struct mlxsw_afk_block *blocks,
213 unsigned int blocks_count);
214void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
215
216struct mlxsw_afk_key_info;
217
218struct mlxsw_afk_key_info *
219mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
220 struct mlxsw_afk_element_usage *elusage);
221void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
222bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
223 struct mlxsw_afk_element_usage *elusage);
224
225u16
226mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
227 int block_index);
228unsigned int
229mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
230
231struct mlxsw_afk_element_values {
232 struct mlxsw_afk_element_usage elusage;
233 struct {
234 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
235 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
236 } storage;
237};
238
239void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
240 enum mlxsw_afk_element element,
241 u32 key_value, u32 mask_value);
242void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
243 enum mlxsw_afk_element element,
244 const char *key_value, const char *mask_value,
245 unsigned int len);
246void mlxsw_afk_encode(struct mlxsw_afk_key_info *key_info,
247 struct mlxsw_afk_element_values *values,
248 char *key, char *mask);
249
250#endif
251