mlxsw: spectrum_acl: Implement region migration according to hints
[linux-2.6-block.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
10 #include "reg.h"
11 #include "spectrum.h"
12 #include "core_acl_flex_keys.h"
13
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 */
24 };
25
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);
34
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,
43                             bool ingress);
44         void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
45                                struct mlxsw_sp_port *mlxsw_sp_port,
46                                bool ingress);
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,
56                                  bool *activity);
57 };
58
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);
62
63 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
64 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
65
66 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
67
68 #define MLXSW_SP_ACL_TCAM_MASK_LEN \
69         (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
70
71 struct mlxsw_sp_acl_tcam_group;
72 struct mlxsw_sp_acl_tcam_vregion;
73
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 */
83 };
84
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;
89 };
90
91 struct mlxsw_sp_acl_ctcam_chunk {
92         struct parman_prio parman_prio;
93 };
94
95 struct mlxsw_sp_acl_ctcam_entry {
96         struct parman_item parman_item;
97 };
98
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,
102                             const char *mask);
103         void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
104                              struct mlxsw_sp_acl_ctcam_entry *centry);
105 };
106
107 int
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)
133 {
134         return centry->parman_item.index;
135 }
136
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,
143 };
144
145 #define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
146         (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
147
148 struct mlxsw_sp_acl_atcam {
149         struct mlxsw_sp_acl_erp_core *erp_core;
150 };
151
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;
161         void *priv;
162 };
163
164 struct mlxsw_sp_acl_atcam_entry_ht_key {
165         char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded
166                                                                  * key.
167                                                                  */
168         u8 erp_id;
169 };
170
171 struct mlxsw_sp_acl_atcam_chunk {
172         struct mlxsw_sp_acl_ctcam_chunk cchunk;
173 };
174
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,
180                                                             * minus delta bits.
181                                                             */
182         struct {
183                 u16 start;
184                 u8 mask;
185                 u8 value;
186         } delta_info;
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;
190 };
191
192 static inline struct mlxsw_sp_acl_atcam_region *
193 mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
194 {
195         return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
196 }
197
198 static inline struct mlxsw_sp_acl_atcam_entry *
199 mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
200 {
201         return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
202 }
203
204 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
205                                         u16 region_id);
206 int
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,
211                                void *hints_priv,
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);
235 void *
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);
238
239 struct mlxsw_sp_acl_erp_delta;
240
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);
247
248 struct mlxsw_sp_acl_erp_mask;
249
250 bool
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);
268 void *
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,
272                                  void *hints_priv);
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);
278
279 struct mlxsw_sp_acl_bf;
280
281 int
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);
287 void
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);
296
297 #endif