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 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 */
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 int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
32 struct mlxsw_sp_acl_rule_info *rulei,
33 u32 *priority, bool fillup_priority);
35 struct mlxsw_sp_acl_profile_ops {
36 size_t ruleset_priv_size;
37 int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
38 struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv,
39 struct mlxsw_afk_element_usage *tmplt_elusage);
40 void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
41 int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
42 struct mlxsw_sp_port *mlxsw_sp_port,
44 void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
45 struct mlxsw_sp_port *mlxsw_sp_port,
47 u16 (*ruleset_group_id)(void *ruleset_priv);
48 size_t rule_priv_size;
49 int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
50 void *ruleset_priv, void *rule_priv,
51 struct mlxsw_sp_acl_rule_info *rulei);
52 void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
53 int (*rule_action_replace)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
54 struct mlxsw_sp_acl_rule_info *rulei);
55 int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
59 const struct mlxsw_sp_acl_profile_ops *
60 mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
61 enum mlxsw_sp_acl_profile profile);
63 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
64 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
66 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
68 #define MLXSW_SP_ACL_TCAM_MASK_LEN \
69 (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
71 struct mlxsw_sp_acl_tcam_group;
72 struct mlxsw_sp_acl_tcam_vregion;
74 struct mlxsw_sp_acl_tcam_region {
75 struct mlxsw_sp_acl_tcam_vregion *vregion;
76 enum mlxsw_reg_ptar_key_type key_type;
77 u16 id; /* ACL ID and region ID - they are same */
78 char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
79 struct mlxsw_afk_key_info *key_info;
80 struct mlxsw_sp *mlxsw_sp;
81 unsigned long priv[0];
82 /* priv has to be always the last item */
85 struct mlxsw_sp_acl_ctcam_region {
86 struct parman *parman;
87 const struct mlxsw_sp_acl_ctcam_region_ops *ops;
88 struct mlxsw_sp_acl_tcam_region *region;
91 struct mlxsw_sp_acl_ctcam_chunk {
92 struct parman_prio parman_prio;
95 struct mlxsw_sp_acl_ctcam_entry {
96 struct parman_item parman_item;
99 struct mlxsw_sp_acl_ctcam_region_ops {
100 int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion,
101 struct mlxsw_sp_acl_ctcam_entry *centry,
103 void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
104 struct mlxsw_sp_acl_ctcam_entry *centry);
108 mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
109 struct mlxsw_sp_acl_ctcam_region *cregion,
110 struct mlxsw_sp_acl_tcam_region *region,
111 const struct mlxsw_sp_acl_ctcam_region_ops *ops);
112 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
113 void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
114 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
115 unsigned int priority);
116 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
117 int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
118 struct mlxsw_sp_acl_ctcam_region *cregion,
119 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
120 struct mlxsw_sp_acl_ctcam_entry *centry,
121 struct mlxsw_sp_acl_rule_info *rulei,
122 bool fillup_priority);
123 void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
124 struct mlxsw_sp_acl_ctcam_region *cregion,
125 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
126 struct mlxsw_sp_acl_ctcam_entry *centry);
127 int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
128 struct mlxsw_sp_acl_ctcam_region *cregion,
129 struct mlxsw_sp_acl_ctcam_entry *centry,
130 struct mlxsw_sp_acl_rule_info *rulei);
131 static inline unsigned int
132 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
134 return centry->parman_item.index;
137 enum mlxsw_sp_acl_atcam_region_type {
138 MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB,
139 MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB,
140 MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB,
141 MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB,
142 __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX,
145 #define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
146 (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
148 struct mlxsw_sp_acl_atcam {
149 struct mlxsw_sp_acl_erp_core *erp_core;
152 struct mlxsw_sp_acl_atcam_region {
153 struct rhashtable entries_ht; /* A-TCAM only */
154 struct list_head entries_list; /* A-TCAM only */
155 struct mlxsw_sp_acl_ctcam_region cregion;
156 const struct mlxsw_sp_acl_atcam_region_ops *ops;
157 struct mlxsw_sp_acl_tcam_region *region;
158 struct mlxsw_sp_acl_atcam *atcam;
159 enum mlxsw_sp_acl_atcam_region_type type;
160 struct mlxsw_sp_acl_erp_table *erp_table;
164 struct mlxsw_sp_acl_atcam_entry_ht_key {
165 char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded
171 struct mlxsw_sp_acl_atcam_chunk {
172 struct mlxsw_sp_acl_ctcam_chunk cchunk;
175 struct mlxsw_sp_acl_atcam_entry {
176 struct rhash_head ht_node;
177 struct list_head list; /* Member in entries_list */
178 struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
179 char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key,
187 struct mlxsw_sp_acl_ctcam_entry centry;
188 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
189 struct mlxsw_sp_acl_erp_mask *erp_mask;
192 static inline struct mlxsw_sp_acl_atcam_region *
193 mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
195 return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
198 static inline struct mlxsw_sp_acl_atcam_entry *
199 mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
201 return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
204 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
207 mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
208 struct mlxsw_sp_acl_atcam *atcam,
209 struct mlxsw_sp_acl_atcam_region *aregion,
210 struct mlxsw_sp_acl_tcam_region *region,
212 const struct mlxsw_sp_acl_ctcam_region_ops *ops);
213 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
214 void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
215 struct mlxsw_sp_acl_atcam_chunk *achunk,
216 unsigned int priority);
217 void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk);
218 int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
219 struct mlxsw_sp_acl_atcam_region *aregion,
220 struct mlxsw_sp_acl_atcam_chunk *achunk,
221 struct mlxsw_sp_acl_atcam_entry *aentry,
222 struct mlxsw_sp_acl_rule_info *rulei);
223 void mlxsw_sp_acl_atcam_entry_del(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 int mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
228 struct mlxsw_sp_acl_atcam_region *aregion,
229 struct mlxsw_sp_acl_atcam_entry *aentry,
230 struct mlxsw_sp_acl_rule_info *rulei);
231 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
232 struct mlxsw_sp_acl_atcam *atcam);
233 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
234 struct mlxsw_sp_acl_atcam *atcam);
236 mlxsw_sp_acl_atcam_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion);
237 void mlxsw_sp_acl_atcam_rehash_hints_put(void *hints_priv);
239 struct mlxsw_sp_acl_erp_delta;
241 u16 mlxsw_sp_acl_erp_delta_start(const struct mlxsw_sp_acl_erp_delta *delta);
242 u8 mlxsw_sp_acl_erp_delta_mask(const struct mlxsw_sp_acl_erp_delta *delta);
243 u8 mlxsw_sp_acl_erp_delta_value(const struct mlxsw_sp_acl_erp_delta *delta,
244 const char *enc_key);
245 void mlxsw_sp_acl_erp_delta_clear(const struct mlxsw_sp_acl_erp_delta *delta,
246 const char *enc_key);
248 struct mlxsw_sp_acl_erp_mask;
251 mlxsw_sp_acl_erp_mask_is_ctcam(const struct mlxsw_sp_acl_erp_mask *erp_mask);
252 u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask);
253 const struct mlxsw_sp_acl_erp_delta *
254 mlxsw_sp_acl_erp_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask);
255 struct mlxsw_sp_acl_erp_mask *
256 mlxsw_sp_acl_erp_mask_get(struct mlxsw_sp_acl_atcam_region *aregion,
257 const char *mask, bool ctcam);
258 void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion,
259 struct mlxsw_sp_acl_erp_mask *erp_mask);
260 int mlxsw_sp_acl_erp_bf_insert(struct mlxsw_sp *mlxsw_sp,
261 struct mlxsw_sp_acl_atcam_region *aregion,
262 struct mlxsw_sp_acl_erp_mask *erp_mask,
263 struct mlxsw_sp_acl_atcam_entry *aentry);
264 void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp,
265 struct mlxsw_sp_acl_atcam_region *aregion,
266 struct mlxsw_sp_acl_erp_mask *erp_mask,
267 struct mlxsw_sp_acl_atcam_entry *aentry);
269 mlxsw_sp_acl_erp_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion);
270 void mlxsw_sp_acl_erp_rehash_hints_put(void *hints_priv);
271 int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion,
273 void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
274 int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
275 struct mlxsw_sp_acl_atcam *atcam);
276 void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
277 struct mlxsw_sp_acl_atcam *atcam);
279 struct mlxsw_sp_acl_bf;
282 mlxsw_sp_acl_bf_entry_add(struct mlxsw_sp *mlxsw_sp,
283 struct mlxsw_sp_acl_bf *bf,
284 struct mlxsw_sp_acl_atcam_region *aregion,
285 unsigned int erp_bank,
286 struct mlxsw_sp_acl_atcam_entry *aentry);
288 mlxsw_sp_acl_bf_entry_del(struct mlxsw_sp *mlxsw_sp,
289 struct mlxsw_sp_acl_bf *bf,
290 struct mlxsw_sp_acl_atcam_region *aregion,
291 unsigned int erp_bank,
292 struct mlxsw_sp_acl_atcam_entry *aentry);
293 struct mlxsw_sp_acl_bf *
294 mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks);
295 void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf);