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