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