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