]> Git Repo - linux.git/blob - drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
crypto: akcipher - Drop sign/verify operations
[linux.git] / drivers / net / ethernet / microchip / sparx5 / sparx5_vcap_impl.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip Sparx5 Switch driver VCAP implementation
3  *
4  * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
5  *
6  * The Sparx5 Chip Register Model can be browsed at this location:
7  * https://github.com/microchip-ung/sparx-5_reginfo
8  */
9
10 #include "vcap_api_debugfs.h"
11 #include "sparx5_main_regs.h"
12 #include "sparx5_main.h"
13 #include "sparx5_vcap_impl.h"
14 #include "sparx5_vcap_ag_api.h"
15 #include "sparx5_vcap_debugfs.h"
16
17 #define SUPER_VCAP_BLK_SIZE 3072 /* addresses per Super VCAP block */
18 #define STREAMSIZE (64 * 4)  /* bytes in the VCAP cache area */
19
20 #define SPARX5_IS2_LOOKUPS 4
21 #define VCAP_IS2_KEYSEL(_ena, _noneth, _v4_mc, _v4_uc, _v6_mc, _v6_uc, _arp) \
22         (ANA_ACL_VCAP_S2_KEY_SEL_KEY_SEL_ENA_SET(_ena) | \
23          ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(_noneth) | \
24          ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(_v4_mc) | \
25          ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(_v4_uc) | \
26          ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(_v6_mc) | \
27          ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(_v6_uc) | \
28          ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(_arp))
29
30 #define SPARX5_IS0_LOOKUPS 6
31 #define VCAP_IS0_KEYSEL(_ena, _etype, _ipv4, _ipv6, _mpls_uc, _mpls_mc, _mlbs) \
32         (ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(_ena) | \
33         ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(_etype) | \
34         ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(_ipv4) | \
35         ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(_ipv6) | \
36         ANA_CL_ADV_CL_CFG_MPLS_UC_CLM_KEY_SEL_SET(_mpls_uc) | \
37         ANA_CL_ADV_CL_CFG_MPLS_MC_CLM_KEY_SEL_SET(_mpls_mc) | \
38         ANA_CL_ADV_CL_CFG_MLBS_CLM_KEY_SEL_SET(_mlbs))
39
40 #define SPARX5_ES0_LOOKUPS 1
41 #define VCAP_ES0_KEYSEL(_key) (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_SET(_key))
42 #define SPARX5_STAT_ESDX_GRN_PKTS  0x300
43 #define SPARX5_STAT_ESDX_YEL_PKTS  0x301
44
45 #define SPARX5_ES2_LOOKUPS 2
46 #define VCAP_ES2_KEYSEL(_ena, _arp, _ipv4, _ipv6) \
47         (EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(_ena) | \
48         EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(_arp) | \
49         EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(_ipv4) | \
50         EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(_ipv6))
51
52 static struct sparx5_vcap_inst {
53         enum vcap_type vtype; /* type of vcap */
54         int vinst; /* instance number within the same type */
55         int lookups; /* number of lookups in this vcap type */
56         int lookups_per_instance; /* number of lookups in this instance */
57         int first_cid; /* first chain id in this vcap */
58         int last_cid; /* last chain id in this vcap */
59         int count; /* number of available addresses, not in super vcap */
60         int map_id; /* id in the super vcap block mapping (if applicable) */
61         int blockno; /* starting block in super vcap (if applicable) */
62         int blocks; /* number of blocks in super vcap (if applicable) */
63         bool ingress; /* is vcap in the ingress path */
64 } sparx5_vcap_inst_cfg[] = {
65         {
66                 .vtype = VCAP_TYPE_IS0, /* CLM-0 */
67                 .vinst = 0,
68                 .map_id = 1,
69                 .lookups = SPARX5_IS0_LOOKUPS,
70                 .lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
71                 .first_cid = SPARX5_VCAP_CID_IS0_L0,
72                 .last_cid = SPARX5_VCAP_CID_IS0_L2 - 1,
73                 .blockno = 8, /* Maps block 8-9 */
74                 .blocks = 2,
75                 .ingress = true,
76         },
77         {
78                 .vtype = VCAP_TYPE_IS0, /* CLM-1 */
79                 .vinst = 1,
80                 .map_id = 2,
81                 .lookups = SPARX5_IS0_LOOKUPS,
82                 .lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
83                 .first_cid = SPARX5_VCAP_CID_IS0_L2,
84                 .last_cid = SPARX5_VCAP_CID_IS0_L4 - 1,
85                 .blockno = 6, /* Maps block 6-7 */
86                 .blocks = 2,
87                 .ingress = true,
88         },
89         {
90                 .vtype = VCAP_TYPE_IS0, /* CLM-2 */
91                 .vinst = 2,
92                 .map_id = 3,
93                 .lookups = SPARX5_IS0_LOOKUPS,
94                 .lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
95                 .first_cid = SPARX5_VCAP_CID_IS0_L4,
96                 .last_cid = SPARX5_VCAP_CID_IS0_MAX,
97                 .blockno = 4, /* Maps block 4-5 */
98                 .blocks = 2,
99                 .ingress = true,
100         },
101         {
102                 .vtype = VCAP_TYPE_IS2, /* IS2-0 */
103                 .vinst = 0,
104                 .map_id = 4,
105                 .lookups = SPARX5_IS2_LOOKUPS,
106                 .lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
107                 .first_cid = SPARX5_VCAP_CID_IS2_L0,
108                 .last_cid = SPARX5_VCAP_CID_IS2_L2 - 1,
109                 .blockno = 0, /* Maps block 0-1 */
110                 .blocks = 2,
111                 .ingress = true,
112         },
113         {
114                 .vtype = VCAP_TYPE_IS2, /* IS2-1 */
115                 .vinst = 1,
116                 .map_id = 5,
117                 .lookups = SPARX5_IS2_LOOKUPS,
118                 .lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
119                 .first_cid = SPARX5_VCAP_CID_IS2_L2,
120                 .last_cid = SPARX5_VCAP_CID_IS2_MAX,
121                 .blockno = 2, /* Maps block 2-3 */
122                 .blocks = 2,
123                 .ingress = true,
124         },
125         {
126                 .vtype = VCAP_TYPE_ES0,
127                 .lookups = SPARX5_ES0_LOOKUPS,
128                 .lookups_per_instance = SPARX5_ES0_LOOKUPS,
129                 .first_cid = SPARX5_VCAP_CID_ES0_L0,
130                 .last_cid = SPARX5_VCAP_CID_ES0_MAX,
131                 .count = 4096, /* Addresses according to datasheet */
132                 .ingress = false,
133         },
134         {
135                 .vtype = VCAP_TYPE_ES2,
136                 .lookups = SPARX5_ES2_LOOKUPS,
137                 .lookups_per_instance = SPARX5_ES2_LOOKUPS,
138                 .first_cid = SPARX5_VCAP_CID_ES2_L0,
139                 .last_cid = SPARX5_VCAP_CID_ES2_MAX,
140                 .count = 12288, /* Addresses according to datasheet */
141                 .ingress = false,
142         },
143 };
144
145 /* These protocols have dedicated keysets in IS0 and a TC dissector */
146 static u16 sparx5_vcap_is0_known_etypes[] = {
147         ETH_P_ALL,
148         ETH_P_IP,
149         ETH_P_IPV6,
150 };
151
152 /* These protocols have dedicated keysets in IS2 and a TC dissector */
153 static u16 sparx5_vcap_is2_known_etypes[] = {
154         ETH_P_ALL,
155         ETH_P_ARP,
156         ETH_P_IP,
157         ETH_P_IPV6,
158 };
159
160 /* These protocols have dedicated keysets in ES2 and a TC dissector */
161 static u16 sparx5_vcap_es2_known_etypes[] = {
162         ETH_P_ALL,
163         ETH_P_ARP,
164         ETH_P_IP,
165         ETH_P_IPV6,
166 };
167
168 static void sparx5_vcap_type_err(struct sparx5 *sparx5,
169                                  struct vcap_admin *admin,
170                                  const char *fname)
171 {
172         pr_err("%s: vcap type: %s not supported\n",
173                fname, sparx5_vcaps[admin->vtype].name);
174 }
175
176 /* Await the super VCAP completion of the current operation */
177 static void sparx5_vcap_wait_super_update(struct sparx5 *sparx5)
178 {
179         u32 value;
180
181         read_poll_timeout(spx5_rd, value,
182                           !VCAP_SUPER_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
183                           false, sparx5, VCAP_SUPER_CTRL);
184 }
185
186 /* Await the ES0 VCAP completion of the current operation */
187 static void sparx5_vcap_wait_es0_update(struct sparx5 *sparx5)
188 {
189         u32 value;
190
191         read_poll_timeout(spx5_rd, value,
192                           !VCAP_ES0_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
193                           false, sparx5, VCAP_ES0_CTRL);
194 }
195
196 /* Await the ES2 VCAP completion of the current operation */
197 static void sparx5_vcap_wait_es2_update(struct sparx5 *sparx5)
198 {
199         u32 value;
200
201         read_poll_timeout(spx5_rd, value,
202                           !VCAP_ES2_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
203                           false, sparx5, VCAP_ES2_CTRL);
204 }
205
206 /* Initializing a VCAP address range */
207 static void _sparx5_vcap_range_init(struct sparx5 *sparx5,
208                                     struct vcap_admin *admin,
209                                     u32 addr, u32 count)
210 {
211         u32 size = count - 1;
212
213         switch (admin->vtype) {
214         case VCAP_TYPE_IS0:
215         case VCAP_TYPE_IS2:
216                 spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
217                         VCAP_SUPER_CFG_MV_SIZE_SET(size),
218                         sparx5, VCAP_SUPER_CFG);
219                 spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
220                         VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
221                         VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
222                         VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
223                         VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
224                         VCAP_SUPER_CTRL_CLEAR_CACHE_SET(true) |
225                         VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
226                         sparx5, VCAP_SUPER_CTRL);
227                 sparx5_vcap_wait_super_update(sparx5);
228                 break;
229         case VCAP_TYPE_ES0:
230                 spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
231                                 VCAP_ES0_CFG_MV_SIZE_SET(size),
232                         sparx5, VCAP_ES0_CFG);
233                 spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
234                                 VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
235                                 VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
236                                 VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
237                                 VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
238                                 VCAP_ES0_CTRL_CLEAR_CACHE_SET(true) |
239                                 VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
240                         sparx5, VCAP_ES0_CTRL);
241                 sparx5_vcap_wait_es0_update(sparx5);
242                 break;
243         case VCAP_TYPE_ES2:
244                 spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
245                         VCAP_ES2_CFG_MV_SIZE_SET(size),
246                         sparx5, VCAP_ES2_CFG);
247                 spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
248                         VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
249                         VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
250                         VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
251                         VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
252                         VCAP_ES2_CTRL_CLEAR_CACHE_SET(true) |
253                         VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
254                         sparx5, VCAP_ES2_CTRL);
255                 sparx5_vcap_wait_es2_update(sparx5);
256                 break;
257         default:
258                 sparx5_vcap_type_err(sparx5, admin, __func__);
259                 break;
260         }
261 }
262
263 /* Initializing VCAP rule data area */
264 static void sparx5_vcap_block_init(struct sparx5 *sparx5,
265                                    struct vcap_admin *admin)
266 {
267         _sparx5_vcap_range_init(sparx5, admin, admin->first_valid_addr,
268                                 admin->last_valid_addr -
269                                         admin->first_valid_addr);
270 }
271
272 /* Get the keyset name from the sparx5 VCAP model */
273 static const char *sparx5_vcap_keyset_name(struct net_device *ndev,
274                                            enum vcap_keyfield_set keyset)
275 {
276         struct sparx5_port *port = netdev_priv(ndev);
277
278         return vcap_keyset_name(port->sparx5->vcap_ctrl, keyset);
279 }
280
281 /* Check if this is the first lookup of IS0 */
282 static bool sparx5_vcap_is0_is_first_chain(struct vcap_rule *rule)
283 {
284         return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L0 &&
285                 rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L1) ||
286                 ((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L2 &&
287                   rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L3)) ||
288                 ((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L4 &&
289                   rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L5));
290 }
291
292 /* Check if this is the first lookup of IS2 */
293 static bool sparx5_vcap_is2_is_first_chain(struct vcap_rule *rule)
294 {
295         return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L0 &&
296                 rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L1) ||
297                 ((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L2 &&
298                   rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L3));
299 }
300
301 static bool sparx5_vcap_es2_is_first_chain(struct vcap_rule *rule)
302 {
303         return (rule->vcap_chain_id >= SPARX5_VCAP_CID_ES2_L0 &&
304                 rule->vcap_chain_id < SPARX5_VCAP_CID_ES2_L1);
305 }
306
307 /* Set the narrow range ingress port mask on a rule */
308 static void sparx5_vcap_add_ingress_range_port_mask(struct vcap_rule *rule,
309                                                     struct net_device *ndev)
310 {
311         struct sparx5_port *port = netdev_priv(ndev);
312         u32 port_mask;
313         u32 range;
314
315         range = port->portno / BITS_PER_TYPE(u32);
316         /* Port bit set to match-any */
317         port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
318         vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_SEL, 0, 0xf);
319         vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_RNG, range, 0xf);
320         vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0, port_mask);
321 }
322
323 /* Set the wide range ingress port mask on a rule */
324 static void sparx5_vcap_add_wide_port_mask(struct vcap_rule *rule,
325                                            struct net_device *ndev)
326 {
327         struct sparx5_port *port = netdev_priv(ndev);
328         struct vcap_u72_key port_mask;
329         u32 range;
330
331         /* Port bit set to match-any */
332         memset(port_mask.value, 0, sizeof(port_mask.value));
333         memset(port_mask.mask, 0xff, sizeof(port_mask.mask));
334         range = port->portno / BITS_PER_BYTE;
335         port_mask.mask[range] = ~BIT(port->portno % BITS_PER_BYTE);
336         vcap_rule_add_key_u72(rule, VCAP_KF_IF_IGR_PORT_MASK, &port_mask);
337 }
338
339 static void sparx5_vcap_add_egress_range_port_mask(struct vcap_rule *rule,
340                                                    struct net_device *ndev)
341 {
342         struct sparx5_port *port = netdev_priv(ndev);
343         u32 port_mask;
344         u32 range;
345
346         /* Mask range selects:
347          * 0-2: Physical/Logical egress port number 0-31, 32–63, 64.
348          * 3-5: Virtual Interface Number 0-31, 32-63, 64.
349          * 6: CPU queue Number 0-7.
350          *
351          * Use physical/logical port ranges (0-2)
352          */
353         range = port->portno / BITS_PER_TYPE(u32);
354         /* Port bit set to match-any */
355         port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
356         vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK_RNG, range, 0xf);
357         vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK, 0, port_mask);
358 }
359
360 /* Convert IS0 chain id to vcap lookup id */
361 static int sparx5_vcap_is0_cid_to_lookup(int cid)
362 {
363         int lookup = 0;
364
365         if (cid >= SPARX5_VCAP_CID_IS0_L1 && cid < SPARX5_VCAP_CID_IS0_L2)
366                 lookup = 1;
367         else if (cid >= SPARX5_VCAP_CID_IS0_L2 && cid < SPARX5_VCAP_CID_IS0_L3)
368                 lookup = 2;
369         else if (cid >= SPARX5_VCAP_CID_IS0_L3 && cid < SPARX5_VCAP_CID_IS0_L4)
370                 lookup = 3;
371         else if (cid >= SPARX5_VCAP_CID_IS0_L4 && cid < SPARX5_VCAP_CID_IS0_L5)
372                 lookup = 4;
373         else if (cid >= SPARX5_VCAP_CID_IS0_L5 && cid < SPARX5_VCAP_CID_IS0_MAX)
374                 lookup = 5;
375
376         return lookup;
377 }
378
379 /* Convert IS2 chain id to vcap lookup id */
380 static int sparx5_vcap_is2_cid_to_lookup(int cid)
381 {
382         int lookup = 0;
383
384         if (cid >= SPARX5_VCAP_CID_IS2_L1 && cid < SPARX5_VCAP_CID_IS2_L2)
385                 lookup = 1;
386         else if (cid >= SPARX5_VCAP_CID_IS2_L2 && cid < SPARX5_VCAP_CID_IS2_L3)
387                 lookup = 2;
388         else if (cid >= SPARX5_VCAP_CID_IS2_L3 && cid < SPARX5_VCAP_CID_IS2_MAX)
389                 lookup = 3;
390
391         return lookup;
392 }
393
394 /* Convert ES2 chain id to vcap lookup id */
395 static int sparx5_vcap_es2_cid_to_lookup(int cid)
396 {
397         int lookup = 0;
398
399         if (cid >= SPARX5_VCAP_CID_ES2_L1)
400                 lookup = 1;
401
402         return lookup;
403 }
404
405 /* Add ethernet type IS0 keyset to a list */
406 static void
407 sparx5_vcap_is0_get_port_etype_keysets(struct vcap_keyset_list *keysetlist,
408                                        u32 value)
409 {
410         switch (ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_GET(value)) {
411         case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
412                 vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_7TUPLE);
413                 break;
414         case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
415                 vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_5TUPLE_IP4);
416                 break;
417         }
418 }
419
420 /* Return the list of keysets for the vcap port configuration */
421 static int sparx5_vcap_is0_get_port_keysets(struct net_device *ndev,
422                                             int lookup,
423                                             struct vcap_keyset_list *keysetlist,
424                                             u16 l3_proto)
425 {
426         struct sparx5_port *port = netdev_priv(ndev);
427         struct sparx5 *sparx5 = port->sparx5;
428         int portno = port->portno;
429         u32 value;
430
431         value = spx5_rd(sparx5, ANA_CL_ADV_CL_CFG(portno, lookup));
432
433         /* Collect all keysets for the port in a list */
434         if (l3_proto == ETH_P_ALL)
435                 sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
436
437         if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
438                 switch (ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_GET(value)) {
439                 case VCAP_IS0_PS_ETYPE_DEFAULT:
440                         sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
441                                                                value);
442                         break;
443                 case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
444                         vcap_keyset_list_add(keysetlist,
445                                              VCAP_KFS_NORMAL_7TUPLE);
446                         break;
447                 case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
448                         vcap_keyset_list_add(keysetlist,
449                                              VCAP_KFS_NORMAL_5TUPLE_IP4);
450                         break;
451                 }
452
453         if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6)
454                 switch (ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_GET(value)) {
455                 case VCAP_IS0_PS_ETYPE_DEFAULT:
456                         sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
457                                                                value);
458                         break;
459                 case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
460                         vcap_keyset_list_add(keysetlist,
461                                              VCAP_KFS_NORMAL_7TUPLE);
462                         break;
463                 case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
464                         vcap_keyset_list_add(keysetlist,
465                                              VCAP_KFS_NORMAL_5TUPLE_IP4);
466                         break;
467                 }
468
469         if (l3_proto != ETH_P_IP && l3_proto != ETH_P_IPV6)
470                 sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
471         return 0;
472 }
473
474 /* Return the list of keysets for the vcap port configuration */
475 static int sparx5_vcap_is2_get_port_keysets(struct net_device *ndev,
476                                             int lookup,
477                                             struct vcap_keyset_list *keysetlist,
478                                             u16 l3_proto)
479 {
480         struct sparx5_port *port = netdev_priv(ndev);
481         struct sparx5 *sparx5 = port->sparx5;
482         int portno = port->portno;
483         u32 value;
484
485         value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
486
487         /* Collect all keysets for the port in a list */
488         if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
489                 switch (ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
490                 case VCAP_IS2_PS_ARP_MAC_ETYPE:
491                         vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
492                         break;
493                 case VCAP_IS2_PS_ARP_ARP:
494                         vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
495                         break;
496                 }
497         }
498
499         if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
500                 switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_GET(value)) {
501                 case VCAP_IS2_PS_IPV4_UC_MAC_ETYPE:
502                         vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
503                         break;
504                 case VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER:
505                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
506                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
507                         break;
508                 case VCAP_IS2_PS_IPV4_UC_IP_7TUPLE:
509                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
510                         break;
511                 }
512
513                 switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_GET(value)) {
514                 case VCAP_IS2_PS_IPV4_MC_MAC_ETYPE:
515                         vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
516                         break;
517                 case VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER:
518                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
519                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
520                         break;
521                 case VCAP_IS2_PS_IPV4_MC_IP_7TUPLE:
522                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
523                         break;
524                 }
525         }
526
527         if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
528                 switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_GET(value)) {
529                 case VCAP_IS2_PS_IPV6_UC_MAC_ETYPE:
530                         vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
531                         break;
532                 case VCAP_IS2_PS_IPV6_UC_IP_7TUPLE:
533                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
534                         break;
535                 case VCAP_IS2_PS_IPV6_UC_IP6_STD:
536                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
537                         break;
538                 case VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER:
539                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
540                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
541                         break;
542                 }
543
544                 switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_GET(value)) {
545                 case VCAP_IS2_PS_IPV6_MC_MAC_ETYPE:
546                         vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
547                         break;
548                 case VCAP_IS2_PS_IPV6_MC_IP_7TUPLE:
549                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
550                         break;
551                 case VCAP_IS2_PS_IPV6_MC_IP6_STD:
552                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
553                         break;
554                 case VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER:
555                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
556                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
557                         break;
558                 case VCAP_IS2_PS_IPV6_MC_IP6_VID:
559                         /* Not used */
560                         break;
561                 }
562         }
563
564         if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
565             l3_proto != ETH_P_IPV6) {
566                 switch (ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_GET(value)) {
567                 case VCAP_IS2_PS_NONETH_MAC_ETYPE:
568                         /* IS2 non-classified frames generate MAC_ETYPE */
569                         vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
570                         break;
571                 }
572         }
573         return 0;
574 }
575
576 /* Return the keysets for the vcap port IP4 traffic class configuration */
577 static void
578 sparx5_vcap_es2_get_port_ipv4_keysets(struct vcap_keyset_list *keysetlist,
579                                       u32 value)
580 {
581         switch (EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_GET(value)) {
582         case VCAP_ES2_PS_IPV4_MAC_ETYPE:
583                 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
584                 break;
585         case VCAP_ES2_PS_IPV4_IP_7TUPLE:
586                 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
587                 break;
588         case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_VID:
589                 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
590                 break;
591         case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER:
592                 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
593                 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
594                 break;
595         case VCAP_ES2_PS_IPV4_IP4_VID:
596                 /* Not used */
597                 break;
598         case VCAP_ES2_PS_IPV4_IP4_OTHER:
599                 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
600                 break;
601         }
602 }
603
604 /* Return the list of keysets for the vcap port configuration */
605 static int sparx5_vcap_es0_get_port_keysets(struct net_device *ndev,
606                                             struct vcap_keyset_list *keysetlist,
607                                             u16 l3_proto)
608 {
609         struct sparx5_port *port = netdev_priv(ndev);
610         struct sparx5 *sparx5 = port->sparx5;
611         int portno = port->portno;
612         u32 value;
613
614         value = spx5_rd(sparx5, REW_RTAG_ETAG_CTRL(portno));
615
616         /* Collect all keysets for the port in a list */
617         switch (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_GET(value)) {
618         case VCAP_ES0_PS_NORMAL_SELECTION:
619         case VCAP_ES0_PS_FORCE_ISDX_LOOKUPS:
620                 vcap_keyset_list_add(keysetlist, VCAP_KFS_ISDX);
621                 break;
622         default:
623                 break;
624         }
625         return 0;
626 }
627
628 /* Return the list of keysets for the vcap port configuration */
629 static int sparx5_vcap_es2_get_port_keysets(struct net_device *ndev,
630                                             int lookup,
631                                             struct vcap_keyset_list *keysetlist,
632                                             u16 l3_proto)
633 {
634         struct sparx5_port *port = netdev_priv(ndev);
635         struct sparx5 *sparx5 = port->sparx5;
636         int portno = port->portno;
637         u32 value;
638
639         value = spx5_rd(sparx5, EACL_VCAP_ES2_KEY_SEL(portno, lookup));
640
641         /* Collect all keysets for the port in a list */
642         if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
643                 switch (EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
644                 case VCAP_ES2_PS_ARP_MAC_ETYPE:
645                         vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
646                         break;
647                 case VCAP_ES2_PS_ARP_ARP:
648                         vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
649                         break;
650                 }
651         }
652
653         if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
654                 sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist, value);
655
656         if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
657                 switch (EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_GET(value)) {
658                 case VCAP_ES2_PS_IPV6_MAC_ETYPE:
659                         vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
660                         break;
661                 case VCAP_ES2_PS_IPV6_IP_7TUPLE:
662                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
663                         break;
664                 case VCAP_ES2_PS_IPV6_IP_7TUPLE_VID:
665                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
666                         break;
667                 case VCAP_ES2_PS_IPV6_IP_7TUPLE_STD:
668                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
669                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
670                         break;
671                 case VCAP_ES2_PS_IPV6_IP6_VID:
672                         /* Not used */
673                         break;
674                 case VCAP_ES2_PS_IPV6_IP6_STD:
675                         vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
676                         break;
677                 case VCAP_ES2_PS_IPV6_IP4_DOWNGRADE:
678                         sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist,
679                                                               value);
680                         break;
681                 }
682         }
683
684         if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
685             l3_proto != ETH_P_IPV6) {
686                 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
687         }
688         return 0;
689 }
690
691 /* Get the port keyset for the vcap lookup */
692 int sparx5_vcap_get_port_keyset(struct net_device *ndev,
693                                 struct vcap_admin *admin,
694                                 int cid,
695                                 u16 l3_proto,
696                                 struct vcap_keyset_list *kslist)
697 {
698         int lookup, err = -EINVAL;
699         struct sparx5_port *port;
700
701         switch (admin->vtype) {
702         case VCAP_TYPE_IS0:
703                 lookup = sparx5_vcap_is0_cid_to_lookup(cid);
704                 err = sparx5_vcap_is0_get_port_keysets(ndev, lookup, kslist,
705                                                        l3_proto);
706                 break;
707         case VCAP_TYPE_IS2:
708                 lookup = sparx5_vcap_is2_cid_to_lookup(cid);
709                 err = sparx5_vcap_is2_get_port_keysets(ndev, lookup, kslist,
710                                                        l3_proto);
711                 break;
712         case VCAP_TYPE_ES0:
713                 err = sparx5_vcap_es0_get_port_keysets(ndev, kslist, l3_proto);
714                 break;
715         case VCAP_TYPE_ES2:
716                 lookup = sparx5_vcap_es2_cid_to_lookup(cid);
717                 err = sparx5_vcap_es2_get_port_keysets(ndev, lookup, kslist,
718                                                        l3_proto);
719                 break;
720         default:
721                 port = netdev_priv(ndev);
722                 sparx5_vcap_type_err(port->sparx5, admin, __func__);
723                 break;
724         }
725         return err;
726 }
727
728 /* Check if the ethertype is supported by the vcap port classification */
729 bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype)
730 {
731         const u16 *known_etypes;
732         int size, idx;
733
734         switch (admin->vtype) {
735         case VCAP_TYPE_IS0:
736                 known_etypes = sparx5_vcap_is0_known_etypes;
737                 size = ARRAY_SIZE(sparx5_vcap_is0_known_etypes);
738                 break;
739         case VCAP_TYPE_IS2:
740                 known_etypes = sparx5_vcap_is2_known_etypes;
741                 size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes);
742                 break;
743         case VCAP_TYPE_ES0:
744                 return true;
745         case VCAP_TYPE_ES2:
746                 known_etypes = sparx5_vcap_es2_known_etypes;
747                 size = ARRAY_SIZE(sparx5_vcap_es2_known_etypes);
748                 break;
749         default:
750                 return false;
751         }
752         for (idx = 0; idx < size; ++idx)
753                 if (known_etypes[idx] == etype)
754                         return true;
755         return false;
756 }
757
758 /* API callback used for validating a field keyset (check the port keysets) */
759 static enum vcap_keyfield_set
760 sparx5_vcap_validate_keyset(struct net_device *ndev,
761                             struct vcap_admin *admin,
762                             struct vcap_rule *rule,
763                             struct vcap_keyset_list *kslist,
764                             u16 l3_proto)
765 {
766         struct vcap_keyset_list keysetlist = {};
767         enum vcap_keyfield_set keysets[10] = {};
768         struct sparx5_port *port;
769         int idx, jdx, lookup;
770
771         if (!kslist || kslist->cnt == 0)
772                 return VCAP_KFS_NO_VALUE;
773
774         keysetlist.max = ARRAY_SIZE(keysets);
775         keysetlist.keysets = keysets;
776
777         /* Get a list of currently configured keysets in the lookups */
778         switch (admin->vtype) {
779         case VCAP_TYPE_IS0:
780                 lookup = sparx5_vcap_is0_cid_to_lookup(rule->vcap_chain_id);
781                 sparx5_vcap_is0_get_port_keysets(ndev, lookup, &keysetlist,
782                                                  l3_proto);
783                 break;
784         case VCAP_TYPE_IS2:
785                 lookup = sparx5_vcap_is2_cid_to_lookup(rule->vcap_chain_id);
786                 sparx5_vcap_is2_get_port_keysets(ndev, lookup, &keysetlist,
787                                                  l3_proto);
788                 break;
789         case VCAP_TYPE_ES0:
790                 sparx5_vcap_es0_get_port_keysets(ndev, &keysetlist, l3_proto);
791                 break;
792         case VCAP_TYPE_ES2:
793                 lookup = sparx5_vcap_es2_cid_to_lookup(rule->vcap_chain_id);
794                 sparx5_vcap_es2_get_port_keysets(ndev, lookup, &keysetlist,
795                                                  l3_proto);
796                 break;
797         default:
798                 port = netdev_priv(ndev);
799                 sparx5_vcap_type_err(port->sparx5, admin, __func__);
800                 break;
801         }
802
803         /* Check if there is a match and return the match */
804         for (idx = 0; idx < kslist->cnt; ++idx)
805                 for (jdx = 0; jdx < keysetlist.cnt; ++jdx)
806                         if (kslist->keysets[idx] == keysets[jdx])
807                                 return kslist->keysets[idx];
808
809         pr_err("%s:%d: %s not supported in port key selection\n",
810                __func__, __LINE__,
811                sparx5_vcap_keyset_name(ndev, kslist->keysets[0]));
812
813         return -ENOENT;
814 }
815
816 static void sparx5_vcap_ingress_add_default_fields(struct net_device *ndev,
817                                                    struct vcap_admin *admin,
818                                                    struct vcap_rule *rule)
819 {
820         const struct vcap_field *field;
821         bool is_first;
822
823         /* Add ingress port mask matching the net device */
824         field = vcap_lookup_keyfield(rule, VCAP_KF_IF_IGR_PORT_MASK);
825         if (field && field->width == SPX5_PORTS)
826                 sparx5_vcap_add_wide_port_mask(rule, ndev);
827         else if (field && field->width == BITS_PER_TYPE(u32))
828                 sparx5_vcap_add_ingress_range_port_mask(rule, ndev);
829         else
830                 pr_err("%s:%d: %s: could not add an ingress port mask for: %s\n",
831                        __func__, __LINE__, netdev_name(ndev),
832                        sparx5_vcap_keyset_name(ndev, rule->keyset));
833
834         if (admin->vtype == VCAP_TYPE_IS0)
835                 is_first = sparx5_vcap_is0_is_first_chain(rule);
836         else
837                 is_first = sparx5_vcap_is2_is_first_chain(rule);
838
839         /* Add key that selects the first/second lookup */
840         if (is_first)
841                 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
842                                       VCAP_BIT_1);
843         else
844                 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
845                                       VCAP_BIT_0);
846 }
847
848 static void sparx5_vcap_es0_add_default_fields(struct net_device *ndev,
849                                                struct vcap_admin *admin,
850                                                struct vcap_rule *rule)
851 {
852         struct sparx5_port *port = netdev_priv(ndev);
853
854         vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_NO, port->portno, ~0);
855         /* Match untagged frames if there was no VLAN key */
856         vcap_rule_add_key_u32(rule, VCAP_KF_8021Q_TPID, SPX5_TPID_SEL_UNTAGGED,
857                               ~0);
858 }
859
860 static void sparx5_vcap_es2_add_default_fields(struct net_device *ndev,
861                                                struct vcap_admin *admin,
862                                                struct vcap_rule *rule)
863 {
864         const struct vcap_field *field;
865         bool is_first;
866
867         /* Add egress port mask matching the net device */
868         field = vcap_lookup_keyfield(rule, VCAP_KF_IF_EGR_PORT_MASK);
869         if (field)
870                 sparx5_vcap_add_egress_range_port_mask(rule, ndev);
871
872         /* Add key that selects the first/second lookup */
873         is_first = sparx5_vcap_es2_is_first_chain(rule);
874
875         if (is_first)
876                 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
877                                       VCAP_BIT_1);
878         else
879                 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
880                                       VCAP_BIT_0);
881 }
882
883 /* API callback used for adding default fields to a rule */
884 static void sparx5_vcap_add_default_fields(struct net_device *ndev,
885                                            struct vcap_admin *admin,
886                                            struct vcap_rule *rule)
887 {
888         struct sparx5_port *port;
889
890         /* add the lookup bit */
891         switch (admin->vtype) {
892         case VCAP_TYPE_IS0:
893         case VCAP_TYPE_IS2:
894                 sparx5_vcap_ingress_add_default_fields(ndev, admin, rule);
895                 break;
896         case VCAP_TYPE_ES0:
897                 sparx5_vcap_es0_add_default_fields(ndev, admin, rule);
898                 break;
899         case VCAP_TYPE_ES2:
900                 sparx5_vcap_es2_add_default_fields(ndev, admin, rule);
901                 break;
902         default:
903                 port = netdev_priv(ndev);
904                 sparx5_vcap_type_err(port->sparx5, admin, __func__);
905                 break;
906         }
907 }
908
909 /* API callback used for erasing the vcap cache area (not the register area) */
910 static void sparx5_vcap_cache_erase(struct vcap_admin *admin)
911 {
912         memset(admin->cache.keystream, 0, STREAMSIZE);
913         memset(admin->cache.maskstream, 0, STREAMSIZE);
914         memset(admin->cache.actionstream, 0, STREAMSIZE);
915         memset(&admin->cache.counter, 0, sizeof(admin->cache.counter));
916 }
917
918 static void sparx5_vcap_is0_cache_write(struct sparx5 *sparx5,
919                                         struct vcap_admin *admin,
920                                         enum vcap_selection sel,
921                                         u32 start,
922                                         u32 count)
923 {
924         u32 *keystr, *mskstr, *actstr;
925         int idx;
926
927         keystr = &admin->cache.keystream[start];
928         mskstr = &admin->cache.maskstream[start];
929         actstr = &admin->cache.actionstream[start];
930
931         switch (sel) {
932         case VCAP_SEL_ENTRY:
933                 for (idx = 0; idx < count; ++idx) {
934                         /* Avoid 'match-off' by setting value & mask */
935                         spx5_wr(keystr[idx] & mskstr[idx], sparx5,
936                                 VCAP_SUPER_VCAP_ENTRY_DAT(idx));
937                         spx5_wr(~mskstr[idx], sparx5,
938                                 VCAP_SUPER_VCAP_MASK_DAT(idx));
939                 }
940                 break;
941         case VCAP_SEL_ACTION:
942                 for (idx = 0; idx < count; ++idx)
943                         spx5_wr(actstr[idx], sparx5,
944                                 VCAP_SUPER_VCAP_ACTION_DAT(idx));
945                 break;
946         case VCAP_SEL_ALL:
947                 pr_err("%s:%d: cannot write all streams at once\n",
948                        __func__, __LINE__);
949                 break;
950         default:
951                 break;
952         }
953
954         if (sel & VCAP_SEL_COUNTER)
955                 spx5_wr(admin->cache.counter, sparx5,
956                         VCAP_SUPER_VCAP_CNT_DAT(0));
957 }
958
959 static void sparx5_vcap_is2_cache_write(struct sparx5 *sparx5,
960                                         struct vcap_admin *admin,
961                                         enum vcap_selection sel,
962                                         u32 start,
963                                         u32 count)
964 {
965         u32 *keystr, *mskstr, *actstr;
966         int idx;
967
968         keystr = &admin->cache.keystream[start];
969         mskstr = &admin->cache.maskstream[start];
970         actstr = &admin->cache.actionstream[start];
971
972         switch (sel) {
973         case VCAP_SEL_ENTRY:
974                 for (idx = 0; idx < count; ++idx) {
975                         /* Avoid 'match-off' by setting value & mask */
976                         spx5_wr(keystr[idx] & mskstr[idx], sparx5,
977                                 VCAP_SUPER_VCAP_ENTRY_DAT(idx));
978                         spx5_wr(~mskstr[idx], sparx5,
979                                 VCAP_SUPER_VCAP_MASK_DAT(idx));
980                 }
981                 break;
982         case VCAP_SEL_ACTION:
983                 for (idx = 0; idx < count; ++idx)
984                         spx5_wr(actstr[idx], sparx5,
985                                 VCAP_SUPER_VCAP_ACTION_DAT(idx));
986                 break;
987         case VCAP_SEL_ALL:
988                 pr_err("%s:%d: cannot write all streams at once\n",
989                        __func__, __LINE__);
990                 break;
991         default:
992                 break;
993         }
994         if (sel & VCAP_SEL_COUNTER) {
995                 start = start & 0xfff; /* counter limit */
996                 if (admin->vinst == 0)
997                         spx5_wr(admin->cache.counter, sparx5,
998                                 ANA_ACL_CNT_A(start));
999                 else
1000                         spx5_wr(admin->cache.counter, sparx5,
1001                                 ANA_ACL_CNT_B(start));
1002                 spx5_wr(admin->cache.sticky, sparx5,
1003                         VCAP_SUPER_VCAP_CNT_DAT(0));
1004         }
1005 }
1006
1007 /* Use ESDX counters located in the XQS */
1008 static void sparx5_es0_write_esdx_counter(struct sparx5 *sparx5,
1009                                           struct vcap_admin *admin, u32 id)
1010 {
1011         mutex_lock(&sparx5->queue_stats_lock);
1012         spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1013         spx5_wr(admin->cache.counter, sparx5,
1014                 XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS));
1015         spx5_wr(0, sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1016         mutex_unlock(&sparx5->queue_stats_lock);
1017 }
1018
1019 static void sparx5_vcap_es0_cache_write(struct sparx5 *sparx5,
1020                                         struct vcap_admin *admin,
1021                                         enum vcap_selection sel,
1022                                         u32 start,
1023                                         u32 count)
1024 {
1025         u32 *keystr, *mskstr, *actstr;
1026         int idx;
1027
1028         keystr = &admin->cache.keystream[start];
1029         mskstr = &admin->cache.maskstream[start];
1030         actstr = &admin->cache.actionstream[start];
1031
1032         switch (sel) {
1033         case VCAP_SEL_ENTRY:
1034                 for (idx = 0; idx < count; ++idx) {
1035                         /* Avoid 'match-off' by setting value & mask */
1036                         spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1037                                 VCAP_ES0_VCAP_ENTRY_DAT(idx));
1038                         spx5_wr(~mskstr[idx], sparx5,
1039                                 VCAP_ES0_VCAP_MASK_DAT(idx));
1040                 }
1041                 break;
1042         case VCAP_SEL_ACTION:
1043                 for (idx = 0; idx < count; ++idx)
1044                         spx5_wr(actstr[idx], sparx5,
1045                                 VCAP_ES0_VCAP_ACTION_DAT(idx));
1046                 break;
1047         case VCAP_SEL_ALL:
1048                 pr_err("%s:%d: cannot write all streams at once\n",
1049                        __func__, __LINE__);
1050                 break;
1051         default:
1052                 break;
1053         }
1054         if (sel & VCAP_SEL_COUNTER) {
1055                 spx5_wr(admin->cache.counter, sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1056                 sparx5_es0_write_esdx_counter(sparx5, admin, start);
1057         }
1058 }
1059
1060 static void sparx5_vcap_es2_cache_write(struct sparx5 *sparx5,
1061                                         struct vcap_admin *admin,
1062                                         enum vcap_selection sel,
1063                                         u32 start,
1064                                         u32 count)
1065 {
1066         u32 *keystr, *mskstr, *actstr;
1067         int idx;
1068
1069         keystr = &admin->cache.keystream[start];
1070         mskstr = &admin->cache.maskstream[start];
1071         actstr = &admin->cache.actionstream[start];
1072
1073         switch (sel) {
1074         case VCAP_SEL_ENTRY:
1075                 for (idx = 0; idx < count; ++idx) {
1076                         /* Avoid 'match-off' by setting value & mask */
1077                         spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1078                                 VCAP_ES2_VCAP_ENTRY_DAT(idx));
1079                         spx5_wr(~mskstr[idx], sparx5,
1080                                 VCAP_ES2_VCAP_MASK_DAT(idx));
1081                 }
1082                 break;
1083         case VCAP_SEL_ACTION:
1084                 for (idx = 0; idx < count; ++idx)
1085                         spx5_wr(actstr[idx], sparx5,
1086                                 VCAP_ES2_VCAP_ACTION_DAT(idx));
1087                 break;
1088         case VCAP_SEL_ALL:
1089                 pr_err("%s:%d: cannot write all streams at once\n",
1090                        __func__, __LINE__);
1091                 break;
1092         default:
1093                 break;
1094         }
1095         if (sel & VCAP_SEL_COUNTER) {
1096                 start = start & 0x7ff; /* counter limit */
1097                 spx5_wr(admin->cache.counter, sparx5, EACL_ES2_CNT(start));
1098                 spx5_wr(admin->cache.sticky, sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1099         }
1100 }
1101
1102 /* API callback used for writing to the VCAP cache */
1103 static void sparx5_vcap_cache_write(struct net_device *ndev,
1104                                     struct vcap_admin *admin,
1105                                     enum vcap_selection sel,
1106                                     u32 start,
1107                                     u32 count)
1108 {
1109         struct sparx5_port *port = netdev_priv(ndev);
1110         struct sparx5 *sparx5 = port->sparx5;
1111
1112         switch (admin->vtype) {
1113         case VCAP_TYPE_IS0:
1114                 sparx5_vcap_is0_cache_write(sparx5, admin, sel, start, count);
1115                 break;
1116         case VCAP_TYPE_IS2:
1117                 sparx5_vcap_is2_cache_write(sparx5, admin, sel, start, count);
1118                 break;
1119         case VCAP_TYPE_ES0:
1120                 sparx5_vcap_es0_cache_write(sparx5, admin, sel, start, count);
1121                 break;
1122         case VCAP_TYPE_ES2:
1123                 sparx5_vcap_es2_cache_write(sparx5, admin, sel, start, count);
1124                 break;
1125         default:
1126                 sparx5_vcap_type_err(sparx5, admin, __func__);
1127                 break;
1128         }
1129 }
1130
1131 static void sparx5_vcap_is0_cache_read(struct sparx5 *sparx5,
1132                                        struct vcap_admin *admin,
1133                                        enum vcap_selection sel,
1134                                        u32 start,
1135                                        u32 count)
1136 {
1137         u32 *keystr, *mskstr, *actstr;
1138         int idx;
1139
1140         keystr = &admin->cache.keystream[start];
1141         mskstr = &admin->cache.maskstream[start];
1142         actstr = &admin->cache.actionstream[start];
1143
1144         if (sel & VCAP_SEL_ENTRY) {
1145                 for (idx = 0; idx < count; ++idx) {
1146                         keystr[idx] = spx5_rd(sparx5,
1147                                               VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1148                         mskstr[idx] = ~spx5_rd(sparx5,
1149                                                VCAP_SUPER_VCAP_MASK_DAT(idx));
1150                 }
1151         }
1152
1153         if (sel & VCAP_SEL_ACTION)
1154                 for (idx = 0; idx < count; ++idx)
1155                         actstr[idx] = spx5_rd(sparx5,
1156                                               VCAP_SUPER_VCAP_ACTION_DAT(idx));
1157
1158         if (sel & VCAP_SEL_COUNTER) {
1159                 admin->cache.counter =
1160                         spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1161                 admin->cache.sticky =
1162                         spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1163         }
1164 }
1165
1166 static void sparx5_vcap_is2_cache_read(struct sparx5 *sparx5,
1167                                        struct vcap_admin *admin,
1168                                        enum vcap_selection sel,
1169                                        u32 start,
1170                                        u32 count)
1171 {
1172         u32 *keystr, *mskstr, *actstr;
1173         int idx;
1174
1175         keystr = &admin->cache.keystream[start];
1176         mskstr = &admin->cache.maskstream[start];
1177         actstr = &admin->cache.actionstream[start];
1178
1179         if (sel & VCAP_SEL_ENTRY) {
1180                 for (idx = 0; idx < count; ++idx) {
1181                         keystr[idx] = spx5_rd(sparx5,
1182                                               VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1183                         mskstr[idx] = ~spx5_rd(sparx5,
1184                                                VCAP_SUPER_VCAP_MASK_DAT(idx));
1185                 }
1186         }
1187
1188         if (sel & VCAP_SEL_ACTION)
1189                 for (idx = 0; idx < count; ++idx)
1190                         actstr[idx] = spx5_rd(sparx5,
1191                                               VCAP_SUPER_VCAP_ACTION_DAT(idx));
1192
1193         if (sel & VCAP_SEL_COUNTER) {
1194                 start = start & 0xfff; /* counter limit */
1195                 if (admin->vinst == 0)
1196                         admin->cache.counter =
1197                                 spx5_rd(sparx5, ANA_ACL_CNT_A(start));
1198                 else
1199                         admin->cache.counter =
1200                                 spx5_rd(sparx5, ANA_ACL_CNT_B(start));
1201                 admin->cache.sticky =
1202                         spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1203         }
1204 }
1205
1206 /* Use ESDX counters located in the XQS */
1207 static void sparx5_es0_read_esdx_counter(struct sparx5 *sparx5,
1208                                          struct vcap_admin *admin, u32 id)
1209 {
1210         u32 counter;
1211
1212         mutex_lock(&sparx5->queue_stats_lock);
1213         spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1214         counter = spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS)) +
1215                 spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1216         mutex_unlock(&sparx5->queue_stats_lock);
1217         if (counter)
1218                 admin->cache.counter = counter;
1219 }
1220
1221 static void sparx5_vcap_es0_cache_read(struct sparx5 *sparx5,
1222                                        struct vcap_admin *admin,
1223                                        enum vcap_selection sel,
1224                                        u32 start,
1225                                        u32 count)
1226 {
1227         u32 *keystr, *mskstr, *actstr;
1228         int idx;
1229
1230         keystr = &admin->cache.keystream[start];
1231         mskstr = &admin->cache.maskstream[start];
1232         actstr = &admin->cache.actionstream[start];
1233
1234         if (sel & VCAP_SEL_ENTRY) {
1235                 for (idx = 0; idx < count; ++idx) {
1236                         keystr[idx] =
1237                                 spx5_rd(sparx5, VCAP_ES0_VCAP_ENTRY_DAT(idx));
1238                         mskstr[idx] =
1239                                 ~spx5_rd(sparx5, VCAP_ES0_VCAP_MASK_DAT(idx));
1240                 }
1241         }
1242
1243         if (sel & VCAP_SEL_ACTION)
1244                 for (idx = 0; idx < count; ++idx)
1245                         actstr[idx] =
1246                                 spx5_rd(sparx5, VCAP_ES0_VCAP_ACTION_DAT(idx));
1247
1248         if (sel & VCAP_SEL_COUNTER) {
1249                 admin->cache.counter =
1250                         spx5_rd(sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1251                 admin->cache.sticky = admin->cache.counter;
1252                 sparx5_es0_read_esdx_counter(sparx5, admin, start);
1253         }
1254 }
1255
1256 static void sparx5_vcap_es2_cache_read(struct sparx5 *sparx5,
1257                                        struct vcap_admin *admin,
1258                                        enum vcap_selection sel,
1259                                        u32 start,
1260                                        u32 count)
1261 {
1262         u32 *keystr, *mskstr, *actstr;
1263         int idx;
1264
1265         keystr = &admin->cache.keystream[start];
1266         mskstr = &admin->cache.maskstream[start];
1267         actstr = &admin->cache.actionstream[start];
1268
1269         if (sel & VCAP_SEL_ENTRY) {
1270                 for (idx = 0; idx < count; ++idx) {
1271                         keystr[idx] =
1272                                 spx5_rd(sparx5, VCAP_ES2_VCAP_ENTRY_DAT(idx));
1273                         mskstr[idx] =
1274                                 ~spx5_rd(sparx5, VCAP_ES2_VCAP_MASK_DAT(idx));
1275                 }
1276         }
1277
1278         if (sel & VCAP_SEL_ACTION)
1279                 for (idx = 0; idx < count; ++idx)
1280                         actstr[idx] =
1281                                 spx5_rd(sparx5, VCAP_ES2_VCAP_ACTION_DAT(idx));
1282
1283         if (sel & VCAP_SEL_COUNTER) {
1284                 start = start & 0x7ff; /* counter limit */
1285                 admin->cache.counter =
1286                         spx5_rd(sparx5, EACL_ES2_CNT(start));
1287                 admin->cache.sticky =
1288                         spx5_rd(sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1289         }
1290 }
1291
1292 /* API callback used for reading from the VCAP into the VCAP cache */
1293 static void sparx5_vcap_cache_read(struct net_device *ndev,
1294                                    struct vcap_admin *admin,
1295                                    enum vcap_selection sel,
1296                                    u32 start,
1297                                    u32 count)
1298 {
1299         struct sparx5_port *port = netdev_priv(ndev);
1300         struct sparx5 *sparx5 = port->sparx5;
1301
1302         switch (admin->vtype) {
1303         case VCAP_TYPE_IS0:
1304                 sparx5_vcap_is0_cache_read(sparx5, admin, sel, start, count);
1305                 break;
1306         case VCAP_TYPE_IS2:
1307                 sparx5_vcap_is2_cache_read(sparx5, admin, sel, start, count);
1308                 break;
1309         case VCAP_TYPE_ES0:
1310                 sparx5_vcap_es0_cache_read(sparx5, admin, sel, start, count);
1311                 break;
1312         case VCAP_TYPE_ES2:
1313                 sparx5_vcap_es2_cache_read(sparx5, admin, sel, start, count);
1314                 break;
1315         default:
1316                 sparx5_vcap_type_err(sparx5, admin, __func__);
1317                 break;
1318         }
1319 }
1320
1321 /* API callback used for initializing a VCAP address range */
1322 static void sparx5_vcap_range_init(struct net_device *ndev,
1323                                    struct vcap_admin *admin, u32 addr,
1324                                    u32 count)
1325 {
1326         struct sparx5_port *port = netdev_priv(ndev);
1327         struct sparx5 *sparx5 = port->sparx5;
1328
1329         _sparx5_vcap_range_init(sparx5, admin, addr, count);
1330 }
1331
1332 static void sparx5_vcap_super_update(struct sparx5 *sparx5,
1333                                      enum vcap_command cmd,
1334                                      enum vcap_selection sel, u32 addr)
1335 {
1336         bool clear = (cmd == VCAP_CMD_INITIALIZE);
1337
1338         spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
1339                 VCAP_SUPER_CFG_MV_SIZE_SET(0), sparx5, VCAP_SUPER_CFG);
1340         spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1341                 VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1342                 VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1343                 VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1344                 VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1345                 VCAP_SUPER_CTRL_CLEAR_CACHE_SET(clear) |
1346                 VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1347                 sparx5, VCAP_SUPER_CTRL);
1348         sparx5_vcap_wait_super_update(sparx5);
1349 }
1350
1351 static void sparx5_vcap_es0_update(struct sparx5 *sparx5,
1352                                    enum vcap_command cmd,
1353                                    enum vcap_selection sel, u32 addr)
1354 {
1355         bool clear = (cmd == VCAP_CMD_INITIALIZE);
1356
1357         spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
1358                 VCAP_ES0_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES0_CFG);
1359         spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1360                 VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1361                 VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1362                 VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1363                 VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1364                 VCAP_ES0_CTRL_CLEAR_CACHE_SET(clear) |
1365                 VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1366                 sparx5, VCAP_ES0_CTRL);
1367         sparx5_vcap_wait_es0_update(sparx5);
1368 }
1369
1370 static void sparx5_vcap_es2_update(struct sparx5 *sparx5,
1371                                    enum vcap_command cmd,
1372                                    enum vcap_selection sel, u32 addr)
1373 {
1374         bool clear = (cmd == VCAP_CMD_INITIALIZE);
1375
1376         spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
1377                 VCAP_ES2_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES2_CFG);
1378         spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1379                 VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1380                 VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1381                 VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1382                 VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1383                 VCAP_ES2_CTRL_CLEAR_CACHE_SET(clear) |
1384                 VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1385                 sparx5, VCAP_ES2_CTRL);
1386         sparx5_vcap_wait_es2_update(sparx5);
1387 }
1388
1389 /* API callback used for updating the VCAP cache */
1390 static void sparx5_vcap_update(struct net_device *ndev,
1391                                struct vcap_admin *admin, enum vcap_command cmd,
1392                                enum vcap_selection sel, u32 addr)
1393 {
1394         struct sparx5_port *port = netdev_priv(ndev);
1395         struct sparx5 *sparx5 = port->sparx5;
1396
1397         switch (admin->vtype) {
1398         case VCAP_TYPE_IS0:
1399         case VCAP_TYPE_IS2:
1400                 sparx5_vcap_super_update(sparx5, cmd, sel, addr);
1401                 break;
1402         case VCAP_TYPE_ES0:
1403                 sparx5_vcap_es0_update(sparx5, cmd, sel, addr);
1404                 break;
1405         case VCAP_TYPE_ES2:
1406                 sparx5_vcap_es2_update(sparx5, cmd, sel, addr);
1407                 break;
1408         default:
1409                 sparx5_vcap_type_err(sparx5, admin, __func__);
1410                 break;
1411         }
1412 }
1413
1414 static void sparx5_vcap_super_move(struct sparx5 *sparx5,
1415                                    u32 addr,
1416                                    enum vcap_command cmd,
1417                                    u16 mv_num_pos,
1418                                    u16 mv_size)
1419 {
1420         spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(mv_num_pos) |
1421                 VCAP_SUPER_CFG_MV_SIZE_SET(mv_size),
1422                 sparx5, VCAP_SUPER_CFG);
1423         spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1424                 VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1425                 VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
1426                 VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
1427                 VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1428                 VCAP_SUPER_CTRL_CLEAR_CACHE_SET(false) |
1429                 VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1430                 sparx5, VCAP_SUPER_CTRL);
1431         sparx5_vcap_wait_super_update(sparx5);
1432 }
1433
1434 static void sparx5_vcap_es0_move(struct sparx5 *sparx5,
1435                                  u32 addr,
1436                                  enum vcap_command cmd,
1437                                  u16 mv_num_pos,
1438                                  u16 mv_size)
1439 {
1440         spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(mv_num_pos) |
1441                 VCAP_ES0_CFG_MV_SIZE_SET(mv_size),
1442                 sparx5, VCAP_ES0_CFG);
1443         spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1444                 VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1445                 VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
1446                 VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
1447                 VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1448                 VCAP_ES0_CTRL_CLEAR_CACHE_SET(false) |
1449                 VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1450                 sparx5, VCAP_ES0_CTRL);
1451         sparx5_vcap_wait_es0_update(sparx5);
1452 }
1453
1454 static void sparx5_vcap_es2_move(struct sparx5 *sparx5,
1455                                  u32 addr,
1456                                  enum vcap_command cmd,
1457                                  u16 mv_num_pos,
1458                                  u16 mv_size)
1459 {
1460         spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(mv_num_pos) |
1461                 VCAP_ES2_CFG_MV_SIZE_SET(mv_size),
1462                 sparx5, VCAP_ES2_CFG);
1463         spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1464                 VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1465                 VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
1466                 VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
1467                 VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1468                 VCAP_ES2_CTRL_CLEAR_CACHE_SET(false) |
1469                 VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1470                 sparx5, VCAP_ES2_CTRL);
1471         sparx5_vcap_wait_es2_update(sparx5);
1472 }
1473
1474 /* API callback used for moving a block of rules in the VCAP */
1475 static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
1476                              u32 addr, int offset, int count)
1477 {
1478         struct sparx5_port *port = netdev_priv(ndev);
1479         struct sparx5 *sparx5 = port->sparx5;
1480         enum vcap_command cmd;
1481         u16 mv_num_pos;
1482         u16 mv_size;
1483
1484         mv_size = count - 1;
1485         if (offset > 0) {
1486                 mv_num_pos = offset - 1;
1487                 cmd = VCAP_CMD_MOVE_DOWN;
1488         } else {
1489                 mv_num_pos = -offset - 1;
1490                 cmd = VCAP_CMD_MOVE_UP;
1491         }
1492
1493         switch (admin->vtype) {
1494         case VCAP_TYPE_IS0:
1495         case VCAP_TYPE_IS2:
1496                 sparx5_vcap_super_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1497                 break;
1498         case VCAP_TYPE_ES0:
1499                 sparx5_vcap_es0_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1500                 break;
1501         case VCAP_TYPE_ES2:
1502                 sparx5_vcap_es2_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1503                 break;
1504         default:
1505                 sparx5_vcap_type_err(sparx5, admin, __func__);
1506                 break;
1507         }
1508 }
1509
1510 static const struct vcap_operations sparx5_vcap_ops = {
1511         .validate_keyset = sparx5_vcap_validate_keyset,
1512         .add_default_fields = sparx5_vcap_add_default_fields,
1513         .cache_erase = sparx5_vcap_cache_erase,
1514         .cache_write = sparx5_vcap_cache_write,
1515         .cache_read = sparx5_vcap_cache_read,
1516         .init = sparx5_vcap_range_init,
1517         .update = sparx5_vcap_update,
1518         .move = sparx5_vcap_move,
1519         .port_info = sparx5_port_info,
1520 };
1521
1522 static u32 sparx5_vcap_is0_keyset_to_etype_ps(enum vcap_keyfield_set keyset)
1523 {
1524         switch (keyset) {
1525         case VCAP_KFS_NORMAL_7TUPLE:
1526                 return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1527         case VCAP_KFS_NORMAL_5TUPLE_IP4:
1528                 return VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4;
1529         default:
1530                 return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1531         }
1532 }
1533
1534 static void sparx5_vcap_is0_set_port_keyset(struct net_device *ndev, int lookup,
1535                                             enum vcap_keyfield_set keyset,
1536                                             int l3_proto)
1537 {
1538         struct sparx5_port *port = netdev_priv(ndev);
1539         struct sparx5 *sparx5 = port->sparx5;
1540         int portno = port->portno;
1541         u32 value;
1542
1543         switch (l3_proto) {
1544         case ETH_P_IP:
1545                 value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1546                 spx5_rmw(ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(value),
1547                          ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL,
1548                          sparx5,
1549                          ANA_CL_ADV_CL_CFG(portno, lookup));
1550                 break;
1551         case ETH_P_IPV6:
1552                 value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1553                 spx5_rmw(ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(value),
1554                          ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL,
1555                          sparx5,
1556                          ANA_CL_ADV_CL_CFG(portno, lookup));
1557                 break;
1558         default:
1559                 value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1560                 spx5_rmw(ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(value),
1561                          ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL,
1562                          sparx5,
1563                          ANA_CL_ADV_CL_CFG(portno, lookup));
1564                 break;
1565         }
1566 }
1567
1568 static u32 sparx5_vcap_is2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1569 {
1570         switch (keyset) {
1571         case VCAP_KFS_ARP:
1572                 return VCAP_IS2_PS_ARP_ARP;
1573         default:
1574                 return VCAP_IS2_PS_ARP_MAC_ETYPE;
1575         }
1576 }
1577
1578 static u32 sparx5_vcap_is2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1579 {
1580         switch (keyset) {
1581         case VCAP_KFS_MAC_ETYPE:
1582                 return VCAP_IS2_PS_IPV4_UC_MAC_ETYPE;
1583         case VCAP_KFS_IP4_OTHER:
1584         case VCAP_KFS_IP4_TCP_UDP:
1585                 return VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER;
1586         case VCAP_KFS_IP_7TUPLE:
1587                 return VCAP_IS2_PS_IPV4_UC_IP_7TUPLE;
1588         default:
1589                 return VCAP_KFS_NO_VALUE;
1590         }
1591 }
1592
1593 static u32 sparx5_vcap_is2_keyset_to_ipv6_uc_ps(enum vcap_keyfield_set keyset)
1594 {
1595         switch (keyset) {
1596         case VCAP_KFS_MAC_ETYPE:
1597                 return VCAP_IS2_PS_IPV6_UC_MAC_ETYPE;
1598         case VCAP_KFS_IP4_OTHER:
1599         case VCAP_KFS_IP4_TCP_UDP:
1600                 return VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER;
1601         case VCAP_KFS_IP_7TUPLE:
1602                 return VCAP_IS2_PS_IPV6_UC_IP_7TUPLE;
1603         default:
1604                 return VCAP_KFS_NO_VALUE;
1605         }
1606 }
1607
1608 static u32 sparx5_vcap_is2_keyset_to_ipv6_mc_ps(enum vcap_keyfield_set keyset)
1609 {
1610         switch (keyset) {
1611         case VCAP_KFS_MAC_ETYPE:
1612                 return VCAP_IS2_PS_IPV6_MC_MAC_ETYPE;
1613         case VCAP_KFS_IP4_OTHER:
1614         case VCAP_KFS_IP4_TCP_UDP:
1615                 return VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER;
1616         case VCAP_KFS_IP_7TUPLE:
1617                 return VCAP_IS2_PS_IPV6_MC_IP_7TUPLE;
1618         default:
1619                 return VCAP_KFS_NO_VALUE;
1620         }
1621 }
1622
1623 static void sparx5_vcap_is2_set_port_keyset(struct net_device *ndev, int lookup,
1624                                             enum vcap_keyfield_set keyset,
1625                                             int l3_proto)
1626 {
1627         struct sparx5_port *port = netdev_priv(ndev);
1628         struct sparx5 *sparx5 = port->sparx5;
1629         int portno = port->portno;
1630         u32 value;
1631
1632         switch (l3_proto) {
1633         case ETH_P_ARP:
1634                 value = sparx5_vcap_is2_keyset_to_arp_ps(keyset);
1635                 spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(value),
1636                          ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL,
1637                          sparx5,
1638                          ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1639                 break;
1640         case ETH_P_IP:
1641                 value = sparx5_vcap_is2_keyset_to_ipv4_ps(keyset);
1642                 spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(value),
1643                          ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL,
1644                          sparx5,
1645                          ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1646                 spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(value),
1647                          ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL,
1648                          sparx5,
1649                          ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1650                 break;
1651         case ETH_P_IPV6:
1652                 value = sparx5_vcap_is2_keyset_to_ipv6_uc_ps(keyset);
1653                 spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(value),
1654                          ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL,
1655                          sparx5,
1656                          ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1657                 value = sparx5_vcap_is2_keyset_to_ipv6_mc_ps(keyset);
1658                 spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(value),
1659                          ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL,
1660                          sparx5,
1661                          ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1662                 break;
1663         default:
1664                 value = VCAP_IS2_PS_NONETH_MAC_ETYPE;
1665                 spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(value),
1666                          ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL,
1667                          sparx5,
1668                          ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1669                 break;
1670         }
1671 }
1672
1673 static u32 sparx5_vcap_es2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1674 {
1675         switch (keyset) {
1676         case VCAP_KFS_ARP:
1677                 return VCAP_ES2_PS_ARP_ARP;
1678         default:
1679                 return VCAP_ES2_PS_ARP_MAC_ETYPE;
1680         }
1681 }
1682
1683 static u32 sparx5_vcap_es2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1684 {
1685         switch (keyset) {
1686         case VCAP_KFS_MAC_ETYPE:
1687                 return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1688         case VCAP_KFS_IP_7TUPLE:
1689                 return VCAP_ES2_PS_IPV4_IP_7TUPLE;
1690         case VCAP_KFS_IP4_TCP_UDP:
1691                 return VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER;
1692         case VCAP_KFS_IP4_OTHER:
1693                 return VCAP_ES2_PS_IPV4_IP4_OTHER;
1694         default:
1695                 return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1696         }
1697 }
1698
1699 static u32 sparx5_vcap_es2_keyset_to_ipv6_ps(enum vcap_keyfield_set keyset)
1700 {
1701         switch (keyset) {
1702         case VCAP_KFS_MAC_ETYPE:
1703                 return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1704         case VCAP_KFS_IP4_TCP_UDP:
1705         case VCAP_KFS_IP4_OTHER:
1706                 return VCAP_ES2_PS_IPV6_IP4_DOWNGRADE;
1707         case VCAP_KFS_IP_7TUPLE:
1708                 return VCAP_ES2_PS_IPV6_IP_7TUPLE;
1709         case VCAP_KFS_IP6_STD:
1710                 return VCAP_ES2_PS_IPV6_IP6_STD;
1711         default:
1712                 return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1713         }
1714 }
1715
1716 static void sparx5_vcap_es2_set_port_keyset(struct net_device *ndev, int lookup,
1717                                             enum vcap_keyfield_set keyset,
1718                                             int l3_proto)
1719 {
1720         struct sparx5_port *port = netdev_priv(ndev);
1721         struct sparx5 *sparx5 = port->sparx5;
1722         int portno = port->portno;
1723         u32 value;
1724
1725         switch (l3_proto) {
1726         case ETH_P_IP:
1727                 value = sparx5_vcap_es2_keyset_to_ipv4_ps(keyset);
1728                 spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(value),
1729                          EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL,
1730                          sparx5,
1731                          EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1732                 break;
1733         case ETH_P_IPV6:
1734                 value = sparx5_vcap_es2_keyset_to_ipv6_ps(keyset);
1735                 spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(value),
1736                          EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL,
1737                          sparx5,
1738                          EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1739                 break;
1740         case ETH_P_ARP:
1741                 value = sparx5_vcap_es2_keyset_to_arp_ps(keyset);
1742                 spx5_rmw(EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(value),
1743                          EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL,
1744                          sparx5,
1745                          EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1746                 break;
1747         }
1748 }
1749
1750 /* Change the port keyset for the lookup and protocol */
1751 void sparx5_vcap_set_port_keyset(struct net_device *ndev,
1752                                  struct vcap_admin *admin,
1753                                  int cid,
1754                                  u16 l3_proto,
1755                                  enum vcap_keyfield_set keyset,
1756                                  struct vcap_keyset_list *orig)
1757 {
1758         struct sparx5_port *port;
1759         int lookup;
1760
1761         switch (admin->vtype) {
1762         case VCAP_TYPE_IS0:
1763                 lookup = sparx5_vcap_is0_cid_to_lookup(cid);
1764                 if (orig)
1765                         sparx5_vcap_is0_get_port_keysets(ndev, lookup, orig,
1766                                                          l3_proto);
1767                 sparx5_vcap_is0_set_port_keyset(ndev, lookup, keyset, l3_proto);
1768                 break;
1769         case VCAP_TYPE_IS2:
1770                 lookup = sparx5_vcap_is2_cid_to_lookup(cid);
1771                 if (orig)
1772                         sparx5_vcap_is2_get_port_keysets(ndev, lookup, orig,
1773                                                          l3_proto);
1774                 sparx5_vcap_is2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1775                 break;
1776         case VCAP_TYPE_ES0:
1777                 break;
1778         case VCAP_TYPE_ES2:
1779                 lookup = sparx5_vcap_es2_cid_to_lookup(cid);
1780                 if (orig)
1781                         sparx5_vcap_es2_get_port_keysets(ndev, lookup, orig,
1782                                                          l3_proto);
1783                 sparx5_vcap_es2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1784                 break;
1785         default:
1786                 port = netdev_priv(ndev);
1787                 sparx5_vcap_type_err(port->sparx5, admin, __func__);
1788                 break;
1789         }
1790 }
1791
1792 /* Enable IS0 lookups per port and set the keyset generation */
1793 static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5,
1794                                                struct vcap_admin *admin)
1795 {
1796         int portno, lookup;
1797         u32 keysel;
1798
1799         keysel = VCAP_IS0_KEYSEL(false,
1800                                  VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1801                                  VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4,
1802                                  VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1803                                  VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1804                                  VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1805                                  VCAP_IS0_PS_MLBS_FOLLOW_ETYPE);
1806         for (lookup = 0; lookup < admin->lookups; ++lookup) {
1807                 for (portno = 0; portno < SPX5_PORTS; ++portno) {
1808                         spx5_wr(keysel, sparx5,
1809                                 ANA_CL_ADV_CL_CFG(portno, lookup));
1810                         spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1811                                  ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1812                                  sparx5,
1813                                  ANA_CL_ADV_CL_CFG(portno, lookup));
1814                 }
1815         }
1816 }
1817
1818 /* Enable IS2 lookups per port and set the keyset generation */
1819 static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
1820                                                struct vcap_admin *admin)
1821 {
1822         int portno, lookup;
1823         u32 keysel;
1824
1825         keysel = VCAP_IS2_KEYSEL(true, VCAP_IS2_PS_NONETH_MAC_ETYPE,
1826                                  VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
1827                                  VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
1828                                  VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
1829                                  VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
1830                                  VCAP_IS2_PS_ARP_ARP);
1831         for (lookup = 0; lookup < admin->lookups; ++lookup) {
1832                 for (portno = 0; portno < SPX5_PORTS; ++portno) {
1833                         spx5_wr(keysel, sparx5,
1834                                 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1835                 }
1836         }
1837         /* IS2 lookups are in bit 0:3 */
1838         for (portno = 0; portno < SPX5_PORTS; ++portno)
1839                 spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
1840                          ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1841                          sparx5,
1842                          ANA_ACL_VCAP_S2_CFG(portno));
1843 }
1844
1845 /* Enable ES0 lookups per port and set the keyset generation */
1846 static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5,
1847                                                struct vcap_admin *admin)
1848 {
1849         int portno;
1850         u32 keysel;
1851
1852         keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS);
1853         for (portno = 0; portno < SPX5_PORTS; ++portno)
1854                 spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA,
1855                          sparx5, REW_RTAG_ETAG_CTRL(portno));
1856
1857         spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(1), REW_ES0_CTRL_ES0_LU_ENA,
1858                  sparx5, REW_ES0_CTRL);
1859 }
1860
1861 /* Enable ES2 lookups per port and set the keyset generation */
1862 static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
1863                                                struct vcap_admin *admin)
1864 {
1865         int portno, lookup;
1866         u32 keysel;
1867
1868         keysel = VCAP_ES2_KEYSEL(true, VCAP_ES2_PS_ARP_MAC_ETYPE,
1869                                  VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
1870                                  VCAP_ES2_PS_IPV6_IP_7TUPLE);
1871         for (lookup = 0; lookup < admin->lookups; ++lookup)
1872                 for (portno = 0; portno < SPX5_PORTS; ++portno)
1873                         spx5_wr(keysel, sparx5,
1874                                 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1875 }
1876
1877 /* Enable lookups per port and set the keyset generation */
1878 static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
1879                                            struct vcap_admin *admin)
1880 {
1881         switch (admin->vtype) {
1882         case VCAP_TYPE_IS0:
1883                 sparx5_vcap_is0_port_key_selection(sparx5, admin);
1884                 break;
1885         case VCAP_TYPE_IS2:
1886                 sparx5_vcap_is2_port_key_selection(sparx5, admin);
1887                 break;
1888         case VCAP_TYPE_ES0:
1889                 sparx5_vcap_es0_port_key_selection(sparx5, admin);
1890                 break;
1891         case VCAP_TYPE_ES2:
1892                 sparx5_vcap_es2_port_key_selection(sparx5, admin);
1893                 break;
1894         default:
1895                 sparx5_vcap_type_err(sparx5, admin, __func__);
1896                 break;
1897         }
1898 }
1899
1900 /* Disable lookups per port */
1901 static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
1902                                              struct vcap_admin *admin)
1903 {
1904         int portno, lookup;
1905
1906         switch (admin->vtype) {
1907         case VCAP_TYPE_IS0:
1908                 for (lookup = 0; lookup < admin->lookups; ++lookup)
1909                         for (portno = 0; portno < SPX5_PORTS; ++portno)
1910                                 spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0),
1911                                          ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1912                                          sparx5,
1913                                          ANA_CL_ADV_CL_CFG(portno, lookup));
1914                 break;
1915         case VCAP_TYPE_IS2:
1916                 for (portno = 0; portno < SPX5_PORTS; ++portno)
1917                         spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0),
1918                                  ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1919                                  sparx5,
1920                                  ANA_ACL_VCAP_S2_CFG(portno));
1921                 break;
1922         case VCAP_TYPE_ES0:
1923                 spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(0),
1924                          REW_ES0_CTRL_ES0_LU_ENA, sparx5, REW_ES0_CTRL);
1925                 break;
1926         case VCAP_TYPE_ES2:
1927                 for (lookup = 0; lookup < admin->lookups; ++lookup)
1928                         for (portno = 0; portno < SPX5_PORTS; ++portno)
1929                                 spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0),
1930                                          EACL_VCAP_ES2_KEY_SEL_KEY_ENA,
1931                                          sparx5,
1932                                          EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1933                 break;
1934         default:
1935                 sparx5_vcap_type_err(sparx5, admin, __func__);
1936                 break;
1937         }
1938 }
1939
1940 static void sparx5_vcap_admin_free(struct vcap_admin *admin)
1941 {
1942         if (!admin)
1943                 return;
1944         mutex_destroy(&admin->lock);
1945         kfree(admin->cache.keystream);
1946         kfree(admin->cache.maskstream);
1947         kfree(admin->cache.actionstream);
1948         kfree(admin);
1949 }
1950
1951 /* Allocate a vcap instance with a rule list and a cache area */
1952 static struct vcap_admin *
1953 sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl,
1954                         const struct sparx5_vcap_inst *cfg)
1955 {
1956         struct vcap_admin *admin;
1957
1958         admin = kzalloc(sizeof(*admin), GFP_KERNEL);
1959         if (!admin)
1960                 return ERR_PTR(-ENOMEM);
1961         INIT_LIST_HEAD(&admin->list);
1962         INIT_LIST_HEAD(&admin->rules);
1963         INIT_LIST_HEAD(&admin->enabled);
1964         mutex_init(&admin->lock);
1965         admin->vtype = cfg->vtype;
1966         admin->vinst = cfg->vinst;
1967         admin->ingress = cfg->ingress;
1968         admin->lookups = cfg->lookups;
1969         admin->lookups_per_instance = cfg->lookups_per_instance;
1970         admin->first_cid = cfg->first_cid;
1971         admin->last_cid = cfg->last_cid;
1972         admin->cache.keystream =
1973                 kzalloc(STREAMSIZE, GFP_KERNEL);
1974         admin->cache.maskstream =
1975                 kzalloc(STREAMSIZE, GFP_KERNEL);
1976         admin->cache.actionstream =
1977                 kzalloc(STREAMSIZE, GFP_KERNEL);
1978         if (!admin->cache.keystream || !admin->cache.maskstream ||
1979             !admin->cache.actionstream) {
1980                 sparx5_vcap_admin_free(admin);
1981                 return ERR_PTR(-ENOMEM);
1982         }
1983         return admin;
1984 }
1985
1986 /* Do block allocations and provide addresses for VCAP instances */
1987 static void sparx5_vcap_block_alloc(struct sparx5 *sparx5,
1988                                     struct vcap_admin *admin,
1989                                     const struct sparx5_vcap_inst *cfg)
1990 {
1991         int idx, cores;
1992
1993         switch (admin->vtype) {
1994         case VCAP_TYPE_IS0:
1995         case VCAP_TYPE_IS2:
1996                 /* Super VCAP block mapping and address configuration. Block 0
1997                  * is assigned addresses 0 through 3071, block 1 is assigned
1998                  * addresses 3072 though 6143, and so on.
1999                  */
2000                 for (idx = cfg->blockno; idx < cfg->blockno + cfg->blocks;
2001                      ++idx) {
2002                         spx5_wr(VCAP_SUPER_IDX_CORE_IDX_SET(idx), sparx5,
2003                                 VCAP_SUPER_IDX);
2004                         spx5_wr(VCAP_SUPER_MAP_CORE_MAP_SET(cfg->map_id),
2005                                 sparx5, VCAP_SUPER_MAP);
2006                 }
2007                 admin->first_valid_addr = cfg->blockno * SUPER_VCAP_BLK_SIZE;
2008                 admin->last_used_addr = admin->first_valid_addr +
2009                         cfg->blocks * SUPER_VCAP_BLK_SIZE;
2010                 admin->last_valid_addr = admin->last_used_addr - 1;
2011                 break;
2012         case VCAP_TYPE_ES0:
2013                 admin->first_valid_addr = 0;
2014                 admin->last_used_addr = cfg->count;
2015                 admin->last_valid_addr = cfg->count - 1;
2016                 cores = spx5_rd(sparx5, VCAP_ES0_CORE_CNT);
2017                 for (idx = 0; idx < cores; ++idx) {
2018                         spx5_wr(VCAP_ES0_IDX_CORE_IDX_SET(idx), sparx5,
2019                                 VCAP_ES0_IDX);
2020                         spx5_wr(VCAP_ES0_MAP_CORE_MAP_SET(1), sparx5,
2021                                 VCAP_ES0_MAP);
2022                 }
2023                 break;
2024         case VCAP_TYPE_ES2:
2025                 admin->first_valid_addr = 0;
2026                 admin->last_used_addr = cfg->count;
2027                 admin->last_valid_addr = cfg->count - 1;
2028                 cores = spx5_rd(sparx5, VCAP_ES2_CORE_CNT);
2029                 for (idx = 0; idx < cores; ++idx) {
2030                         spx5_wr(VCAP_ES2_IDX_CORE_IDX_SET(idx), sparx5,
2031                                 VCAP_ES2_IDX);
2032                         spx5_wr(VCAP_ES2_MAP_CORE_MAP_SET(1), sparx5,
2033                                 VCAP_ES2_MAP);
2034                 }
2035                 break;
2036         default:
2037                 sparx5_vcap_type_err(sparx5, admin, __func__);
2038                 break;
2039         }
2040 }
2041
2042 /* Allocate a vcap control and vcap instances and configure the system */
2043 int sparx5_vcap_init(struct sparx5 *sparx5)
2044 {
2045         const struct sparx5_vcap_inst *cfg;
2046         struct vcap_control *ctrl;
2047         struct vcap_admin *admin;
2048         struct dentry *dir;
2049         int err = 0, idx;
2050
2051         /* Create a VCAP control instance that owns the platform specific VCAP
2052          * model with VCAP instances and information about keysets, keys,
2053          * actionsets and actions
2054          * - Create administrative state for each available VCAP
2055          *   - Lists of rules
2056          *   - Address information
2057          *   - Initialize VCAP blocks
2058          *   - Configure port keysets
2059          */
2060         ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
2061         if (!ctrl)
2062                 return -ENOMEM;
2063
2064         sparx5->vcap_ctrl = ctrl;
2065         /* select the sparx5 VCAP model */
2066         ctrl->vcaps = sparx5_vcaps;
2067         ctrl->stats = &sparx5_vcap_stats;
2068         /* Setup callbacks to allow the API to use the VCAP HW */
2069         ctrl->ops = &sparx5_vcap_ops;
2070
2071         INIT_LIST_HEAD(&ctrl->list);
2072         for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) {
2073                 cfg = &sparx5_vcap_inst_cfg[idx];
2074                 admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg);
2075                 if (IS_ERR(admin)) {
2076                         err = PTR_ERR(admin);
2077                         pr_err("%s:%d: vcap allocation failed: %d\n",
2078                                __func__, __LINE__, err);
2079                         return err;
2080                 }
2081                 sparx5_vcap_block_alloc(sparx5, admin, cfg);
2082                 sparx5_vcap_block_init(sparx5, admin);
2083                 if (cfg->vinst == 0)
2084                         sparx5_vcap_port_key_selection(sparx5, admin);
2085                 list_add_tail(&admin->list, &ctrl->list);
2086         }
2087         dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
2088         for (idx = 0; idx < SPX5_PORTS; ++idx)
2089                 if (sparx5->ports[idx])
2090                         vcap_port_debugfs(sparx5->dev, dir, ctrl,
2091                                           sparx5->ports[idx]->ndev);
2092
2093         return err;
2094 }
2095
2096 void sparx5_vcap_destroy(struct sparx5 *sparx5)
2097 {
2098         struct vcap_control *ctrl = sparx5->vcap_ctrl;
2099         struct vcap_admin *admin, *admin_next;
2100
2101         if (!ctrl)
2102                 return;
2103
2104         list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) {
2105                 sparx5_vcap_port_key_deselection(sparx5, admin);
2106                 vcap_del_rules(ctrl, admin);
2107                 list_del(&admin->list);
2108                 sparx5_vcap_admin_free(admin);
2109         }
2110         kfree(ctrl);
2111 }
This page took 0.169141 seconds and 4 git commands to generate.