xref: /linux/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h (revision a5d9265e017f081f0dc133c0e2f45103d027b874)
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_SPECTRUM_ACL_TCAM_H
5 #define _MLXSW_SPECTRUM_ACL_TCAM_H
6 
7 #include <linux/list.h>
8 #include <linux/parman.h>
9 
10 #include "reg.h"
11 #include "spectrum.h"
12 #include "core_acl_flex_keys.h"
13 
14 struct mlxsw_sp_acl_tcam {
15 	unsigned long *used_regions; /* bit array */
16 	unsigned int max_regions;
17 	unsigned long *used_groups;  /* bit array */
18 	unsigned int max_groups;
19 	unsigned int max_group_size;
20 	struct list_head vregion_list;
21 	u32 vregion_rehash_intrvl;   /* ms */
22 	unsigned long priv[0];
23 	/* priv has to be always the last item */
24 };
25 
26 size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp);
27 int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
28 			   struct mlxsw_sp_acl_tcam *tcam);
29 void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
30 			    struct mlxsw_sp_acl_tcam *tcam);
31 u32 mlxsw_sp_acl_tcam_vregion_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp,
32 						struct mlxsw_sp_acl_tcam *tcam);
33 int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp,
34 						struct mlxsw_sp_acl_tcam *tcam,
35 						u32 val);
36 int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
37 				   struct mlxsw_sp_acl_rule_info *rulei,
38 				   u32 *priority, bool fillup_priority);
39 
40 struct mlxsw_sp_acl_profile_ops {
41 	size_t ruleset_priv_size;
42 	int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
43 			   struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv,
44 			   struct mlxsw_afk_element_usage *tmplt_elusage);
45 	void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
46 	int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
47 			    struct mlxsw_sp_port *mlxsw_sp_port,
48 			    bool ingress);
49 	void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
50 			       struct mlxsw_sp_port *mlxsw_sp_port,
51 			       bool ingress);
52 	u16 (*ruleset_group_id)(void *ruleset_priv);
53 	size_t rule_priv_size;
54 	int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
55 			void *ruleset_priv, void *rule_priv,
56 			struct mlxsw_sp_acl_rule_info *rulei);
57 	void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
58 	int (*rule_action_replace)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
59 				   struct mlxsw_sp_acl_rule_info *rulei);
60 	int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
61 				 bool *activity);
62 };
63 
64 const struct mlxsw_sp_acl_profile_ops *
65 mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
66 			      enum mlxsw_sp_acl_profile profile);
67 
68 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
69 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
70 
71 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
72 
73 #define MLXSW_SP_ACL_TCAM_MASK_LEN \
74 	(MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
75 
76 struct mlxsw_sp_acl_tcam_group;
77 struct mlxsw_sp_acl_tcam_vregion;
78 
79 struct mlxsw_sp_acl_tcam_region {
80 	struct mlxsw_sp_acl_tcam_vregion *vregion;
81 	enum mlxsw_reg_ptar_key_type key_type;
82 	u16 id; /* ACL ID and region ID - they are same */
83 	char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
84 	struct mlxsw_afk_key_info *key_info;
85 	struct mlxsw_sp *mlxsw_sp;
86 	unsigned long priv[0];
87 	/* priv has to be always the last item */
88 };
89 
90 struct mlxsw_sp_acl_ctcam_region {
91 	struct parman *parman;
92 	const struct mlxsw_sp_acl_ctcam_region_ops *ops;
93 	struct mlxsw_sp_acl_tcam_region *region;
94 };
95 
96 struct mlxsw_sp_acl_ctcam_chunk {
97 	struct parman_prio parman_prio;
98 };
99 
100 struct mlxsw_sp_acl_ctcam_entry {
101 	struct parman_item parman_item;
102 };
103 
104 struct mlxsw_sp_acl_ctcam_region_ops {
105 	int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion,
106 			    struct mlxsw_sp_acl_ctcam_entry *centry,
107 			    const char *mask);
108 	void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
109 			     struct mlxsw_sp_acl_ctcam_entry *centry);
110 };
111 
112 int
113 mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
114 			       struct mlxsw_sp_acl_ctcam_region *cregion,
115 			       struct mlxsw_sp_acl_tcam_region *region,
116 			       const struct mlxsw_sp_acl_ctcam_region_ops *ops);
117 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
118 void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
119 				   struct mlxsw_sp_acl_ctcam_chunk *cchunk,
120 				   unsigned int priority);
121 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
122 int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
123 				 struct mlxsw_sp_acl_ctcam_region *cregion,
124 				 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
125 				 struct mlxsw_sp_acl_ctcam_entry *centry,
126 				 struct mlxsw_sp_acl_rule_info *rulei,
127 				 bool fillup_priority);
128 void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
129 				  struct mlxsw_sp_acl_ctcam_region *cregion,
130 				  struct mlxsw_sp_acl_ctcam_chunk *cchunk,
131 				  struct mlxsw_sp_acl_ctcam_entry *centry);
132 int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
133 					    struct mlxsw_sp_acl_ctcam_region *cregion,
134 					    struct mlxsw_sp_acl_ctcam_entry *centry,
135 					    struct mlxsw_sp_acl_rule_info *rulei);
136 static inline unsigned int
137 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
138 {
139 	return centry->parman_item.index;
140 }
141 
142 enum mlxsw_sp_acl_atcam_region_type {
143 	MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB,
144 	MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB,
145 	MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB,
146 	MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB,
147 	__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX,
148 };
149 
150 #define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
151 	(__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
152 
153 struct mlxsw_sp_acl_atcam {
154 	struct mlxsw_sp_acl_erp_core *erp_core;
155 };
156 
157 struct mlxsw_sp_acl_atcam_region {
158 	struct rhashtable entries_ht; /* A-TCAM only */
159 	struct list_head entries_list; /* A-TCAM only */
160 	struct mlxsw_sp_acl_ctcam_region cregion;
161 	const struct mlxsw_sp_acl_atcam_region_ops *ops;
162 	struct mlxsw_sp_acl_tcam_region *region;
163 	struct mlxsw_sp_acl_atcam *atcam;
164 	enum mlxsw_sp_acl_atcam_region_type type;
165 	struct mlxsw_sp_acl_erp_table *erp_table;
166 	void *priv;
167 };
168 
169 struct mlxsw_sp_acl_atcam_entry_ht_key {
170 	char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded
171 								 * key.
172 								 */
173 	u8 erp_id;
174 };
175 
176 struct mlxsw_sp_acl_atcam_chunk {
177 	struct mlxsw_sp_acl_ctcam_chunk cchunk;
178 };
179 
180 struct mlxsw_sp_acl_atcam_entry {
181 	struct rhash_head ht_node;
182 	struct list_head list; /* Member in entries_list */
183 	struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
184 	char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key,
185 							    * minus delta bits.
186 							    */
187 	struct {
188 		u16 start;
189 		u8 mask;
190 		u8 value;
191 	} delta_info;
192 	struct mlxsw_sp_acl_ctcam_entry centry;
193 	struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
194 	struct mlxsw_sp_acl_erp_mask *erp_mask;
195 };
196 
197 static inline struct mlxsw_sp_acl_atcam_region *
198 mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
199 {
200 	return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
201 }
202 
203 static inline struct mlxsw_sp_acl_atcam_entry *
204 mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
205 {
206 	return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
207 }
208 
209 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
210 					u16 region_id);
211 int
212 mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
213 			       struct mlxsw_sp_acl_atcam *atcam,
214 			       struct mlxsw_sp_acl_atcam_region *aregion,
215 			       struct mlxsw_sp_acl_tcam_region *region,
216 			       void *hints_priv,
217 			       const struct mlxsw_sp_acl_ctcam_region_ops *ops);
218 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
219 void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
220 				   struct mlxsw_sp_acl_atcam_chunk *achunk,
221 				   unsigned int priority);
222 void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk);
223 int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
224 				 struct mlxsw_sp_acl_atcam_region *aregion,
225 				 struct mlxsw_sp_acl_atcam_chunk *achunk,
226 				 struct mlxsw_sp_acl_atcam_entry *aentry,
227 				 struct mlxsw_sp_acl_rule_info *rulei);
228 void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
229 				  struct mlxsw_sp_acl_atcam_region *aregion,
230 				  struct mlxsw_sp_acl_atcam_chunk *achunk,
231 				  struct mlxsw_sp_acl_atcam_entry *aentry);
232 int mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
233 					    struct mlxsw_sp_acl_atcam_region *aregion,
234 					    struct mlxsw_sp_acl_atcam_entry *aentry,
235 					    struct mlxsw_sp_acl_rule_info *rulei);
236 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
237 			    struct mlxsw_sp_acl_atcam *atcam);
238 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
239 			     struct mlxsw_sp_acl_atcam *atcam);
240 void *
241 mlxsw_sp_acl_atcam_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion);
242 void mlxsw_sp_acl_atcam_rehash_hints_put(void *hints_priv);
243 
244 struct mlxsw_sp_acl_erp_delta;
245 
246 u16 mlxsw_sp_acl_erp_delta_start(const struct mlxsw_sp_acl_erp_delta *delta);
247 u8 mlxsw_sp_acl_erp_delta_mask(const struct mlxsw_sp_acl_erp_delta *delta);
248 u8 mlxsw_sp_acl_erp_delta_value(const struct mlxsw_sp_acl_erp_delta *delta,
249 				const char *enc_key);
250 void mlxsw_sp_acl_erp_delta_clear(const struct mlxsw_sp_acl_erp_delta *delta,
251 				  const char *enc_key);
252 
253 struct mlxsw_sp_acl_erp_mask;
254 
255 bool
256 mlxsw_sp_acl_erp_mask_is_ctcam(const struct mlxsw_sp_acl_erp_mask *erp_mask);
257 u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask);
258 const struct mlxsw_sp_acl_erp_delta *
259 mlxsw_sp_acl_erp_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask);
260 struct mlxsw_sp_acl_erp_mask *
261 mlxsw_sp_acl_erp_mask_get(struct mlxsw_sp_acl_atcam_region *aregion,
262 			  const char *mask, bool ctcam);
263 void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion,
264 			       struct mlxsw_sp_acl_erp_mask *erp_mask);
265 int mlxsw_sp_acl_erp_bf_insert(struct mlxsw_sp *mlxsw_sp,
266 			       struct mlxsw_sp_acl_atcam_region *aregion,
267 			       struct mlxsw_sp_acl_erp_mask *erp_mask,
268 			       struct mlxsw_sp_acl_atcam_entry *aentry);
269 void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp,
270 				struct mlxsw_sp_acl_atcam_region *aregion,
271 				struct mlxsw_sp_acl_erp_mask *erp_mask,
272 				struct mlxsw_sp_acl_atcam_entry *aentry);
273 void *
274 mlxsw_sp_acl_erp_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion);
275 void mlxsw_sp_acl_erp_rehash_hints_put(void *hints_priv);
276 int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion,
277 				 void *hints_priv);
278 void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
279 int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
280 			   struct mlxsw_sp_acl_atcam *atcam);
281 void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
282 			    struct mlxsw_sp_acl_atcam *atcam);
283 
284 struct mlxsw_sp_acl_bf;
285 
286 int
287 mlxsw_sp_acl_bf_entry_add(struct mlxsw_sp *mlxsw_sp,
288 			  struct mlxsw_sp_acl_bf *bf,
289 			  struct mlxsw_sp_acl_atcam_region *aregion,
290 			  unsigned int erp_bank,
291 			  struct mlxsw_sp_acl_atcam_entry *aentry);
292 void
293 mlxsw_sp_acl_bf_entry_del(struct mlxsw_sp *mlxsw_sp,
294 			  struct mlxsw_sp_acl_bf *bf,
295 			  struct mlxsw_sp_acl_atcam_region *aregion,
296 			  unsigned int erp_bank,
297 			  struct mlxsw_sp_acl_atcam_entry *aentry);
298 struct mlxsw_sp_acl_bf *
299 mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks);
300 void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf);
301 
302 #endif
303