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
73
74
75
76static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
77 MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 8),
78 MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_32_47, 0x04, 2),
79 MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_0_31, 0x06, 4),
80 MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_32_47, 0x0A, 2),
81 MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_0_31, 0x0C, 4),
82 MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
83 MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
84 MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
85 MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
86 MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9),
87 MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
88 MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
89 MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
90 MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
91 MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
92 MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_8_10, 0x18, 17, 3),
93 MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_0_7, 0x18, 20, 8),
94 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4),
95 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4),
96 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4),
97 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_0_31, 0x2C, 4),
98 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_96_127, 0x30, 4),
99 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_64_95, 0x34, 4),
100 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4),
101 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4),
102};
103
104#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
105
106struct mlxsw_afk_element_inst {
107 const struct mlxsw_afk_element_info *info;
108 enum mlxsw_afk_element_type type;
109 struct mlxsw_item item;
110};
111
112#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, _shift, _size) \
113 { \
114 .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
115 .type = _type, \
116 .item = { \
117 .offset = _offset, \
118 .shift = _shift, \
119 .size = {.bits = _size}, \
120 .name = #_element, \
121 }, \
122 }
123
124#define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size) \
125 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \
126 _element, _offset, _shift, _size)
127
128#define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size) \
129 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF, \
130 _element, _offset, 0, _size)
131
132struct mlxsw_afk_block {
133 u16 encoding;
134 struct mlxsw_afk_element_inst *instances;
135 unsigned int instances_count;
136};
137
138#define MLXSW_AFK_BLOCK(_encoding, _instances) \
139 { \
140 .encoding = _encoding, \
141 .instances = _instances, \
142 .instances_count = ARRAY_SIZE(_instances), \
143 }
144
145struct mlxsw_afk_element_usage {
146 DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
147};
148
149#define mlxsw_afk_element_usage_for_each(element, elusage) \
150 for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
151
152static inline void
153mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
154 enum mlxsw_afk_element element)
155{
156 __set_bit(element, elusage->usage);
157}
158
159static inline void
160mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
161{
162 bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
163}
164
165static inline void
166mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
167 const enum mlxsw_afk_element *elements,
168 unsigned int elements_count)
169{
170 int i;
171
172 mlxsw_afk_element_usage_zero(elusage);
173 for (i = 0; i < elements_count; i++)
174 mlxsw_afk_element_usage_add(elusage, elements[i]);
175}
176
177static inline bool
178mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
179 struct mlxsw_afk_element_usage *elusage_big)
180{
181 int i;
182
183 for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
184 if (test_bit(i, elusage_small->usage) &&
185 !test_bit(i, elusage_big->usage))
186 return false;
187 return true;
188}
189
190struct mlxsw_afk;
191
192struct mlxsw_afk_ops {
193 const struct mlxsw_afk_block *blocks;
194 unsigned int blocks_count;
195 void (*encode_block)(char *output, int block_index, char *block);
196 void (*clear_block)(char *output, int block_index);
197};
198
199struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
200 const struct mlxsw_afk_ops *ops);
201void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
202
203struct mlxsw_afk_key_info;
204
205struct mlxsw_afk_key_info *
206mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
207 struct mlxsw_afk_element_usage *elusage);
208void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
209bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
210 struct mlxsw_afk_element_usage *elusage);
211
212u16
213mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
214 int block_index);
215unsigned int
216mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
217
218struct mlxsw_afk_element_values {
219 struct mlxsw_afk_element_usage elusage;
220 struct {
221 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
222 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
223 } storage;
224};
225
226void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
227 enum mlxsw_afk_element element,
228 u32 key_value, u32 mask_value);
229void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
230 enum mlxsw_afk_element element,
231 const char *key_value, const char *mask_value,
232 unsigned int len);
233void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
234 struct mlxsw_afk_key_info *key_info,
235 struct mlxsw_afk_element_values *values,
236 char *key, char *mask);
237void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
238 int block_start, int block_end);
239
240#endif
241