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 
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_8_10,
37 	MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_7,
38 	MLXSW_AFK_ELEMENT_MAX,
39 };
40 
41 enum mlxsw_afk_element_type {
42 	MLXSW_AFK_ELEMENT_TYPE_U32,
43 	MLXSW_AFK_ELEMENT_TYPE_BUF,
44 };
45 
46 struct mlxsw_afk_element_info {
47 	enum mlxsw_afk_element element; /* element ID */
48 	enum mlxsw_afk_element_type type;
49 	struct mlxsw_item item; /* element geometry in internal storage */
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 /* For the purpose of the driver, define an internal storage scratchpad
73  * that will be used to store key/mask values. For each defined element type
74  * define an internal storage geometry.
75  */
76 static 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 
106 struct mlxsw_afk_element_inst { /* element instance in actual block */
107 	const struct mlxsw_afk_element_info *info;
108 	enum mlxsw_afk_element_type type;
109 	struct mlxsw_item item; /* element geometry in block */
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 
132 struct mlxsw_afk_block {
133 	u16 encoding; /* block ID */
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 
145 struct 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 
152 static inline void
153 mlxsw_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 
159 static inline void
160 mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
161 {
162 	bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
163 }
164 
165 static inline void
166 mlxsw_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 
177 static inline bool
178 mlxsw_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 
190 struct mlxsw_afk;
191 
192 struct 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 
199 struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
200 				   const struct mlxsw_afk_ops *ops);
201 void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
202 
203 struct mlxsw_afk_key_info;
204 
205 struct mlxsw_afk_key_info *
206 mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
207 		       struct mlxsw_afk_element_usage *elusage);
208 void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
209 bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
210 			       struct mlxsw_afk_element_usage *elusage);
211 
212 u16
213 mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
214 				      int block_index);
215 unsigned int
216 mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
217 
218 struct 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 
226 void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
227 			      enum mlxsw_afk_element element,
228 			      u32 key_value, u32 mask_value);
229 void 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);
233 void 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);
237 void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
238 		     int block_start, int block_end);
239 
240 #endif
241