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 unsigned long priv[0];
21
22};
23
24size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp);
25int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
26 struct mlxsw_sp_acl_tcam *tcam);
27void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
28 struct mlxsw_sp_acl_tcam *tcam);
29int 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);
32
33struct 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,
41 bool ingress);
42 void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
43 struct mlxsw_sp_port *mlxsw_sp_port,
44 bool ingress);
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_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
52 bool *activity);
53};
54
55const struct mlxsw_sp_acl_profile_ops *
56mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
57 enum mlxsw_sp_acl_profile profile);
58
59#define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
60#define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
61
62#define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
63
64#define MLXSW_SP_ACL_TCAM_MASK_LEN \
65 (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
66
67struct mlxsw_sp_acl_tcam_group;
68
69struct mlxsw_sp_acl_tcam_region {
70 struct list_head list;
71 struct list_head chunk_list;
72 struct mlxsw_sp_acl_tcam_group *group;
73 enum mlxsw_reg_ptar_key_type key_type;
74 u16 id;
75 char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
76 struct mlxsw_afk_key_info *key_info;
77 struct mlxsw_sp *mlxsw_sp;
78 unsigned long priv[0];
79
80};
81
82struct mlxsw_sp_acl_ctcam_region {
83 struct parman *parman;
84 const struct mlxsw_sp_acl_ctcam_region_ops *ops;
85 struct mlxsw_sp_acl_tcam_region *region;
86};
87
88struct mlxsw_sp_acl_ctcam_chunk {
89 struct parman_prio parman_prio;
90};
91
92struct mlxsw_sp_acl_ctcam_entry {
93 struct parman_item parman_item;
94};
95
96struct mlxsw_sp_acl_ctcam_region_ops {
97 int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion,
98 struct mlxsw_sp_acl_ctcam_entry *centry,
99 const char *mask);
100 void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
101 struct mlxsw_sp_acl_ctcam_entry *centry);
102};
103
104int
105mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
106 struct mlxsw_sp_acl_ctcam_region *cregion,
107 struct mlxsw_sp_acl_tcam_region *region,
108 const struct mlxsw_sp_acl_ctcam_region_ops *ops);
109void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
110void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
111 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
112 unsigned int priority);
113void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
114int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
115 struct mlxsw_sp_acl_ctcam_region *cregion,
116 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
117 struct mlxsw_sp_acl_ctcam_entry *centry,
118 struct mlxsw_sp_acl_rule_info *rulei,
119 bool fillup_priority);
120void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
121 struct mlxsw_sp_acl_ctcam_region *cregion,
122 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
123 struct mlxsw_sp_acl_ctcam_entry *centry);
124static inline unsigned int
125mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
126{
127 return centry->parman_item.index;
128}
129
130enum mlxsw_sp_acl_atcam_region_type {
131 MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB,
132 MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB,
133 MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB,
134 MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB,
135 __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX,
136};
137
138#define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
139 (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
140
141struct mlxsw_sp_acl_atcam {
142 struct mlxsw_sp_acl_erp_core *erp_core;
143};
144
145struct mlxsw_sp_acl_atcam_region {
146 struct rhashtable entries_ht;
147 struct mlxsw_sp_acl_ctcam_region cregion;
148 const struct mlxsw_sp_acl_atcam_region_ops *ops;
149 struct mlxsw_sp_acl_tcam_region *region;
150 struct mlxsw_sp_acl_atcam *atcam;
151 enum mlxsw_sp_acl_atcam_region_type type;
152 struct mlxsw_sp_acl_erp_table *erp_table;
153 void *priv;
154};
155
156struct mlxsw_sp_acl_atcam_entry_ht_key {
157 char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN];
158 u8 erp_id;
159};
160
161struct mlxsw_sp_acl_atcam_chunk {
162 struct mlxsw_sp_acl_ctcam_chunk cchunk;
163};
164
165struct mlxsw_sp_acl_atcam_entry {
166 struct rhash_head ht_node;
167 struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
168 struct mlxsw_sp_acl_ctcam_entry centry;
169 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
170 struct mlxsw_sp_acl_erp *erp;
171};
172
173static inline struct mlxsw_sp_acl_atcam_region *
174mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
175{
176 return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
177}
178
179static inline struct mlxsw_sp_acl_atcam_entry *
180mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
181{
182 return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
183}
184
185int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
186 u16 region_id);
187int
188mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
189 struct mlxsw_sp_acl_atcam *atcam,
190 struct mlxsw_sp_acl_atcam_region *aregion,
191 struct mlxsw_sp_acl_tcam_region *region,
192 const struct mlxsw_sp_acl_ctcam_region_ops *ops);
193void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
194void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
195 struct mlxsw_sp_acl_atcam_chunk *achunk,
196 unsigned int priority);
197void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk);
198int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
199 struct mlxsw_sp_acl_atcam_region *aregion,
200 struct mlxsw_sp_acl_atcam_chunk *achunk,
201 struct mlxsw_sp_acl_atcam_entry *aentry,
202 struct mlxsw_sp_acl_rule_info *rulei);
203void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
204 struct mlxsw_sp_acl_atcam_region *aregion,
205 struct mlxsw_sp_acl_atcam_chunk *achunk,
206 struct mlxsw_sp_acl_atcam_entry *aentry);
207int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
208 struct mlxsw_sp_acl_atcam *atcam);
209void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
210 struct mlxsw_sp_acl_atcam *atcam);
211
212struct mlxsw_sp_acl_erp;
213
214bool mlxsw_sp_acl_erp_is_ctcam_erp(const struct mlxsw_sp_acl_erp *erp);
215u8 mlxsw_sp_acl_erp_id(const struct mlxsw_sp_acl_erp *erp);
216struct mlxsw_sp_acl_erp *
217mlxsw_sp_acl_erp_get(struct mlxsw_sp_acl_atcam_region *aregion,
218 const char *mask, bool ctcam);
219void mlxsw_sp_acl_erp_put(struct mlxsw_sp_acl_atcam_region *aregion,
220 struct mlxsw_sp_acl_erp *erp);
221int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion);
222void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
223int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
224 struct mlxsw_sp_acl_atcam *atcam);
225void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
226 struct mlxsw_sp_acl_atcam *atcam);
227
228#endif
229