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