1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
4 #ifndef _MLXSW_SPECTRUM_ACL_TCAM_H
5 #define _MLXSW_SPECTRUM_ACL_TCAM_H
7 #include <linux/list.h>
8 #include <linux/parman.h>
12 #include "core_acl_flex_keys.h"
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 unsigned long priv[0];
21 /* priv has to be always the last item */
24 size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp);
25 int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
26 struct mlxsw_sp_acl_tcam *tcam);
27 void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
28 struct mlxsw_sp_acl_tcam *tcam);
29 int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
30 struct mlxsw_sp_acl_rule_info *rulei,
31 u32 *priority, bool fillup_priority);
33 struct mlxsw_sp_acl_profile_ops {
34 size_t ruleset_priv_size;
35 int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
36 struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv,
37 struct mlxsw_afk_element_usage *tmplt_elusage);
38 void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
39 int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
40 struct mlxsw_sp_port *mlxsw_sp_port,
42 void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
43 struct mlxsw_sp_port *mlxsw_sp_port,
45 u16 (*ruleset_group_id)(void *ruleset_priv);
46 size_t (*rule_priv_size)(struct mlxsw_sp *mlxsw_sp);
47 int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
48 void *ruleset_priv, void *rule_priv,
49 struct mlxsw_sp_acl_rule_info *rulei);
50 void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
51 int (*rule_action_replace)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
52 struct mlxsw_sp_acl_rule_info *rulei);
53 int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
57 const struct mlxsw_sp_acl_profile_ops *
58 mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
59 enum mlxsw_sp_acl_profile profile);
61 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
62 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
64 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
66 #define MLXSW_SP_ACL_TCAM_MASK_LEN \
67 (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
69 struct mlxsw_sp_acl_tcam_group;
71 struct mlxsw_sp_acl_tcam_region {
72 struct list_head list; /* Member of a TCAM group */
73 struct list_head chunk_list; /* List of chunks under this region */
74 struct mlxsw_sp_acl_tcam_group *group;
75 enum mlxsw_reg_ptar_key_type key_type;
76 u16 id; /* ACL ID and region ID - they are same */
77 char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
78 struct mlxsw_afk_key_info *key_info;
79 struct mlxsw_sp *mlxsw_sp;
80 unsigned long priv[0];
81 /* priv has to be always the last item */
84 struct mlxsw_sp_acl_ctcam_region {
85 struct parman *parman;
86 const struct mlxsw_sp_acl_ctcam_region_ops *ops;
87 struct mlxsw_sp_acl_tcam_region *region;
90 struct mlxsw_sp_acl_ctcam_chunk {
91 struct parman_prio parman_prio;
94 struct mlxsw_sp_acl_ctcam_entry {
95 struct parman_item parman_item;
98 struct mlxsw_sp_acl_ctcam_region_ops {
99 int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion,
100 struct mlxsw_sp_acl_ctcam_entry *centry,
102 void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
103 struct mlxsw_sp_acl_ctcam_entry *centry);
107 mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
108 struct mlxsw_sp_acl_ctcam_region *cregion,
109 struct mlxsw_sp_acl_tcam_region *region,
110 const struct mlxsw_sp_acl_ctcam_region_ops *ops);
111 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
112 void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
113 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
114 unsigned int priority);
115 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
116 int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
117 struct mlxsw_sp_acl_ctcam_region *cregion,
118 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
119 struct mlxsw_sp_acl_ctcam_entry *centry,
120 struct mlxsw_sp_acl_rule_info *rulei,
121 bool fillup_priority);
122 void mlxsw_sp_acl_ctcam_entry_del(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 int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
127 struct mlxsw_sp_acl_ctcam_region *cregion,
128 struct mlxsw_sp_acl_ctcam_entry *centry,
129 struct mlxsw_sp_acl_rule_info *rulei);
130 static inline unsigned int
131 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
133 return centry->parman_item.index;
136 enum mlxsw_sp_acl_atcam_region_type {
137 MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB,
138 MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB,
139 MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB,
140 MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB,
141 __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX,
144 #define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
145 (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
147 struct mlxsw_sp_acl_atcam {
148 struct mlxsw_sp_acl_erp_core *erp_core;
151 struct mlxsw_sp_acl_atcam_region {
152 struct rhashtable entries_ht; /* A-TCAM only */
153 struct list_head entries_list; /* A-TCAM only */
154 struct mlxsw_sp_acl_ctcam_region cregion;
155 const struct mlxsw_sp_acl_atcam_region_ops *ops;
156 struct mlxsw_sp_acl_tcam_region *region;
157 struct mlxsw_sp_acl_atcam *atcam;
158 enum mlxsw_sp_acl_atcam_region_type type;
159 struct mlxsw_sp_acl_erp_table *erp_table;
163 struct mlxsw_sp_acl_atcam_entry_ht_key {
164 char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded
170 struct mlxsw_sp_acl_atcam_chunk {
171 struct mlxsw_sp_acl_ctcam_chunk cchunk;
174 struct mlxsw_sp_acl_atcam_entry {
175 struct rhash_head ht_node;
176 struct list_head list; /* Member in entries_list */
177 struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
178 char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key,
186 struct mlxsw_sp_acl_ctcam_entry centry;
187 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
188 struct mlxsw_sp_acl_erp_mask *erp_mask;
191 static inline struct mlxsw_sp_acl_atcam_region *
192 mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
194 return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
197 static inline struct mlxsw_sp_acl_atcam_entry *
198 mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
200 return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
203 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
206 mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
207 struct mlxsw_sp_acl_atcam *atcam,
208 struct mlxsw_sp_acl_atcam_region *aregion,
209 struct mlxsw_sp_acl_tcam_region *region,
210 const struct mlxsw_sp_acl_ctcam_region_ops *ops);
211 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
212 void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
213 struct mlxsw_sp_acl_atcam_chunk *achunk,
214 unsigned int priority);
215 void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk);
216 int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
217 struct mlxsw_sp_acl_atcam_region *aregion,
218 struct mlxsw_sp_acl_atcam_chunk *achunk,
219 struct mlxsw_sp_acl_atcam_entry *aentry,
220 struct mlxsw_sp_acl_rule_info *rulei);
221 void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
222 struct mlxsw_sp_acl_atcam_region *aregion,
223 struct mlxsw_sp_acl_atcam_chunk *achunk,
224 struct mlxsw_sp_acl_atcam_entry *aentry);
225 int mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
226 struct mlxsw_sp_acl_atcam_region *aregion,
227 struct mlxsw_sp_acl_atcam_entry *aentry,
228 struct mlxsw_sp_acl_rule_info *rulei);
229 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
230 struct mlxsw_sp_acl_atcam *atcam);
231 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
232 struct mlxsw_sp_acl_atcam *atcam);
234 struct mlxsw_sp_acl_erp_delta;
236 u16 mlxsw_sp_acl_erp_delta_start(const struct mlxsw_sp_acl_erp_delta *delta);
237 u8 mlxsw_sp_acl_erp_delta_mask(const struct mlxsw_sp_acl_erp_delta *delta);
238 u8 mlxsw_sp_acl_erp_delta_value(const struct mlxsw_sp_acl_erp_delta *delta,
239 const char *enc_key);
240 void mlxsw_sp_acl_erp_delta_clear(const struct mlxsw_sp_acl_erp_delta *delta,
241 const char *enc_key);
243 struct mlxsw_sp_acl_erp_mask;
246 mlxsw_sp_acl_erp_mask_is_ctcam(const struct mlxsw_sp_acl_erp_mask *erp_mask);
247 u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask);
248 const struct mlxsw_sp_acl_erp_delta *
249 mlxsw_sp_acl_erp_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask);
250 struct mlxsw_sp_acl_erp_mask *
251 mlxsw_sp_acl_erp_mask_get(struct mlxsw_sp_acl_atcam_region *aregion,
252 const char *mask, bool ctcam);
253 void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion,
254 struct mlxsw_sp_acl_erp_mask *erp_mask);
255 int mlxsw_sp_acl_erp_bf_insert(struct mlxsw_sp *mlxsw_sp,
256 struct mlxsw_sp_acl_atcam_region *aregion,
257 struct mlxsw_sp_acl_erp_mask *erp_mask,
258 struct mlxsw_sp_acl_atcam_entry *aentry);
259 void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp,
260 struct mlxsw_sp_acl_atcam_region *aregion,
261 struct mlxsw_sp_acl_erp_mask *erp_mask,
262 struct mlxsw_sp_acl_atcam_entry *aentry);
263 int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion);
264 void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
265 int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
266 struct mlxsw_sp_acl_atcam *atcam);
267 void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
268 struct mlxsw_sp_acl_atcam *atcam);
270 struct mlxsw_sp_acl_bf;
273 mlxsw_sp_acl_bf_entry_add(struct mlxsw_sp *mlxsw_sp,
274 struct mlxsw_sp_acl_bf *bf,
275 struct mlxsw_sp_acl_atcam_region *aregion,
276 unsigned int erp_bank,
277 struct mlxsw_sp_acl_atcam_entry *aentry);
279 mlxsw_sp_acl_bf_entry_del(struct mlxsw_sp *mlxsw_sp,
280 struct mlxsw_sp_acl_bf *bf,
281 struct mlxsw_sp_acl_atcam_region *aregion,
282 unsigned int erp_bank,
283 struct mlxsw_sp_acl_atcam_entry *aentry);
284 struct mlxsw_sp_acl_bf *
285 mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks);
286 void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf);