GNU Linux-libre 4.19.245-gnu1
[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
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)(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
55 const struct mlxsw_sp_acl_profile_ops *
56 mlxsw_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
67 struct mlxsw_sp_acl_tcam_group;
68
69 struct mlxsw_sp_acl_tcam_region {
70         struct list_head list; /* Member of a TCAM group */
71         struct list_head chunk_list; /* List of chunks under this region */
72         struct mlxsw_sp_acl_tcam_group *group;
73         enum mlxsw_reg_ptar_key_type key_type;
74         u16 id; /* ACL ID and region ID - they are same */
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         /* priv has to be always the last item */
80 };
81
82 struct 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
88 struct mlxsw_sp_acl_ctcam_chunk {
89         struct parman_prio parman_prio;
90 };
91
92 struct mlxsw_sp_acl_ctcam_entry {
93         struct parman_item parman_item;
94 };
95
96 struct 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
104 int
105 mlxsw_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);
109 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
110 void 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);
113 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
114 int 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);
120 void 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);
124 static inline unsigned int
125 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
126 {
127         return centry->parman_item.index;
128 }
129
130 enum 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
141 struct mlxsw_sp_acl_atcam {
142         struct mlxsw_sp_acl_erp_core *erp_core;
143 };
144
145 struct mlxsw_sp_acl_atcam_region {
146         struct rhashtable entries_ht; /* A-TCAM only */
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
156 struct mlxsw_sp_acl_atcam_entry_ht_key {
157         char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key */
158         u8 erp_id;
159 };
160
161 struct mlxsw_sp_acl_atcam_chunk {
162         struct mlxsw_sp_acl_ctcam_chunk cchunk;
163 };
164
165 struct 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
173 static inline struct mlxsw_sp_acl_atcam_region *
174 mlxsw_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
179 static inline struct mlxsw_sp_acl_atcam_entry *
180 mlxsw_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
185 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
186                                         u16 region_id);
187 int
188 mlxsw_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);
193 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
194 void 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);
197 void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk);
198 int 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);
203 void 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);
207 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
208                             struct mlxsw_sp_acl_atcam *atcam);
209 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
210                              struct mlxsw_sp_acl_atcam *atcam);
211
212 struct mlxsw_sp_acl_erp;
213
214 bool mlxsw_sp_acl_erp_is_ctcam_erp(const struct mlxsw_sp_acl_erp *erp);
215 u8 mlxsw_sp_acl_erp_id(const struct mlxsw_sp_acl_erp *erp);
216 struct mlxsw_sp_acl_erp *
217 mlxsw_sp_acl_erp_get(struct mlxsw_sp_acl_atcam_region *aregion,
218                      const char *mask, bool ctcam);
219 void mlxsw_sp_acl_erp_put(struct mlxsw_sp_acl_atcam_region *aregion,
220                           struct mlxsw_sp_acl_erp *erp);
221 int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion);
222 void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
223 int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
224                            struct mlxsw_sp_acl_atcam *atcam);
225 void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
226                             struct mlxsw_sp_acl_atcam *atcam);
227
228 #endif