mlxsw: spectrum_acl: Implement basic ERP rehash hits creation
[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         unsigned long priv[0];
21         /* priv has to be always the last item */
22 };
23
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);
32
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,
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;
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,
54                                  bool *activity);
55 };
56
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);
60
61 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
62 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
63
64 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
65
66 #define MLXSW_SP_ACL_TCAM_MASK_LEN \
67         (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
68
69 struct mlxsw_sp_acl_tcam_group;
70 struct mlxsw_sp_acl_tcam_vregion;
71
72 struct mlxsw_sp_acl_tcam_region {
73         struct mlxsw_sp_acl_tcam_vregion *vregion;
74         enum mlxsw_reg_ptar_key_type key_type;
75         u16 id; /* ACL ID and region ID - they are same */
76         char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
77         struct mlxsw_afk_key_info *key_info;
78         struct mlxsw_sp *mlxsw_sp;
79         unsigned long priv[0];
80         /* priv has to be always the last item */
81 };
82
83 struct mlxsw_sp_acl_ctcam_region {
84         struct parman *parman;
85         const struct mlxsw_sp_acl_ctcam_region_ops *ops;
86         struct mlxsw_sp_acl_tcam_region *region;
87 };
88
89 struct mlxsw_sp_acl_ctcam_chunk {
90         struct parman_prio parman_prio;
91 };
92
93 struct mlxsw_sp_acl_ctcam_entry {
94         struct parman_item parman_item;
95 };
96
97 struct mlxsw_sp_acl_ctcam_region_ops {
98         int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion,
99                             struct mlxsw_sp_acl_ctcam_entry *centry,
100                             const char *mask);
101         void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
102                              struct mlxsw_sp_acl_ctcam_entry *centry);
103 };
104
105 int
106 mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
107                                struct mlxsw_sp_acl_ctcam_region *cregion,
108                                struct mlxsw_sp_acl_tcam_region *region,
109                                const struct mlxsw_sp_acl_ctcam_region_ops *ops);
110 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
111 void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
112                                    struct mlxsw_sp_acl_ctcam_chunk *cchunk,
113                                    unsigned int priority);
114 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
115 int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
116                                  struct mlxsw_sp_acl_ctcam_region *cregion,
117                                  struct mlxsw_sp_acl_ctcam_chunk *cchunk,
118                                  struct mlxsw_sp_acl_ctcam_entry *centry,
119                                  struct mlxsw_sp_acl_rule_info *rulei,
120                                  bool fillup_priority);
121 void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
122                                   struct mlxsw_sp_acl_ctcam_region *cregion,
123                                   struct mlxsw_sp_acl_ctcam_chunk *cchunk,
124                                   struct mlxsw_sp_acl_ctcam_entry *centry);
125 int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
126                                             struct mlxsw_sp_acl_ctcam_region *cregion,
127                                             struct mlxsw_sp_acl_ctcam_entry *centry,
128                                             struct mlxsw_sp_acl_rule_info *rulei);
129 static inline unsigned int
130 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
131 {
132         return centry->parman_item.index;
133 }
134
135 enum mlxsw_sp_acl_atcam_region_type {
136         MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB,
137         MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB,
138         MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB,
139         MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB,
140         __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX,
141 };
142
143 #define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
144         (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
145
146 struct mlxsw_sp_acl_atcam {
147         struct mlxsw_sp_acl_erp_core *erp_core;
148 };
149
150 struct mlxsw_sp_acl_atcam_region {
151         struct rhashtable entries_ht; /* A-TCAM only */
152         struct list_head entries_list; /* A-TCAM only */
153         struct mlxsw_sp_acl_ctcam_region cregion;
154         const struct mlxsw_sp_acl_atcam_region_ops *ops;
155         struct mlxsw_sp_acl_tcam_region *region;
156         struct mlxsw_sp_acl_atcam *atcam;
157         enum mlxsw_sp_acl_atcam_region_type type;
158         struct mlxsw_sp_acl_erp_table *erp_table;
159         void *priv;
160 };
161
162 struct mlxsw_sp_acl_atcam_entry_ht_key {
163         char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded
164                                                                  * key.
165                                                                  */
166         u8 erp_id;
167 };
168
169 struct mlxsw_sp_acl_atcam_chunk {
170         struct mlxsw_sp_acl_ctcam_chunk cchunk;
171 };
172
173 struct mlxsw_sp_acl_atcam_entry {
174         struct rhash_head ht_node;
175         struct list_head list; /* Member in entries_list */
176         struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
177         char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key,
178                                                             * minus delta bits.
179                                                             */
180         struct {
181                 u16 start;
182                 u8 mask;
183                 u8 value;
184         } delta_info;
185         struct mlxsw_sp_acl_ctcam_entry centry;
186         struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
187         struct mlxsw_sp_acl_erp_mask *erp_mask;
188 };
189
190 static inline struct mlxsw_sp_acl_atcam_region *
191 mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
192 {
193         return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
194 }
195
196 static inline struct mlxsw_sp_acl_atcam_entry *
197 mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
198 {
199         return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
200 }
201
202 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
203                                         u16 region_id);
204 int
205 mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
206                                struct mlxsw_sp_acl_atcam *atcam,
207                                struct mlxsw_sp_acl_atcam_region *aregion,
208                                struct mlxsw_sp_acl_tcam_region *region,
209                                const struct mlxsw_sp_acl_ctcam_region_ops *ops);
210 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
211 void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
212                                    struct mlxsw_sp_acl_atcam_chunk *achunk,
213                                    unsigned int priority);
214 void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk);
215 int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
216                                  struct mlxsw_sp_acl_atcam_region *aregion,
217                                  struct mlxsw_sp_acl_atcam_chunk *achunk,
218                                  struct mlxsw_sp_acl_atcam_entry *aentry,
219                                  struct mlxsw_sp_acl_rule_info *rulei);
220 void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
221                                   struct mlxsw_sp_acl_atcam_region *aregion,
222                                   struct mlxsw_sp_acl_atcam_chunk *achunk,
223                                   struct mlxsw_sp_acl_atcam_entry *aentry);
224 int mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
225                                             struct mlxsw_sp_acl_atcam_region *aregion,
226                                             struct mlxsw_sp_acl_atcam_entry *aentry,
227                                             struct mlxsw_sp_acl_rule_info *rulei);
228 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
229                             struct mlxsw_sp_acl_atcam *atcam);
230 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
231                              struct mlxsw_sp_acl_atcam *atcam);
232 void *
233 mlxsw_sp_acl_atcam_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion);
234 void mlxsw_sp_acl_atcam_rehash_hints_put(void *hints_priv);
235
236 struct mlxsw_sp_acl_erp_delta;
237
238 u16 mlxsw_sp_acl_erp_delta_start(const struct mlxsw_sp_acl_erp_delta *delta);
239 u8 mlxsw_sp_acl_erp_delta_mask(const struct mlxsw_sp_acl_erp_delta *delta);
240 u8 mlxsw_sp_acl_erp_delta_value(const struct mlxsw_sp_acl_erp_delta *delta,
241                                 const char *enc_key);
242 void mlxsw_sp_acl_erp_delta_clear(const struct mlxsw_sp_acl_erp_delta *delta,
243                                   const char *enc_key);
244
245 struct mlxsw_sp_acl_erp_mask;
246
247 bool
248 mlxsw_sp_acl_erp_mask_is_ctcam(const struct mlxsw_sp_acl_erp_mask *erp_mask);
249 u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask);
250 const struct mlxsw_sp_acl_erp_delta *
251 mlxsw_sp_acl_erp_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask);
252 struct mlxsw_sp_acl_erp_mask *
253 mlxsw_sp_acl_erp_mask_get(struct mlxsw_sp_acl_atcam_region *aregion,
254                           const char *mask, bool ctcam);
255 void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion,
256                                struct mlxsw_sp_acl_erp_mask *erp_mask);
257 int mlxsw_sp_acl_erp_bf_insert(struct mlxsw_sp *mlxsw_sp,
258                                struct mlxsw_sp_acl_atcam_region *aregion,
259                                struct mlxsw_sp_acl_erp_mask *erp_mask,
260                                struct mlxsw_sp_acl_atcam_entry *aentry);
261 void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp,
262                                 struct mlxsw_sp_acl_atcam_region *aregion,
263                                 struct mlxsw_sp_acl_erp_mask *erp_mask,
264                                 struct mlxsw_sp_acl_atcam_entry *aentry);
265 void *
266 mlxsw_sp_acl_erp_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion);
267 void mlxsw_sp_acl_erp_rehash_hints_put(void *hints_priv);
268 int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion);
269 void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
270 int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
271                            struct mlxsw_sp_acl_atcam *atcam);
272 void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
273                             struct mlxsw_sp_acl_atcam *atcam);
274
275 struct mlxsw_sp_acl_bf;
276
277 int
278 mlxsw_sp_acl_bf_entry_add(struct mlxsw_sp *mlxsw_sp,
279                           struct mlxsw_sp_acl_bf *bf,
280                           struct mlxsw_sp_acl_atcam_region *aregion,
281                           unsigned int erp_bank,
282                           struct mlxsw_sp_acl_atcam_entry *aentry);
283 void
284 mlxsw_sp_acl_bf_entry_del(struct mlxsw_sp *mlxsw_sp,
285                           struct mlxsw_sp_acl_bf *bf,
286                           struct mlxsw_sp_acl_atcam_region *aregion,
287                           unsigned int erp_bank,
288                           struct mlxsw_sp_acl_atcam_entry *aentry);
289 struct mlxsw_sp_acl_bf *
290 mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks);
291 void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf);
292
293 #endif