1 // SPDX-License-Identifier: GPL-2.0+
2 
3 #include "lan966x_main.h"
4 #include "lan966x_vcap_ag_api.h"
5 #include "vcap_api.h"
6 #include "vcap_api_client.h"
7 #include "vcap_api_debugfs.h"
8 
9 #define STREAMSIZE (64 * 4)
10 
11 #define LAN966X_IS1_LOOKUPS 3
12 #define LAN966X_IS2_LOOKUPS 2
13 
14 static struct lan966x_vcap_inst {
15 	enum vcap_type vtype; /* type of vcap */
16 	int tgt_inst; /* hardware instance number */
17 	int lookups; /* number of lookups in this vcap type */
18 	int first_cid; /* first chain id in this vcap */
19 	int last_cid; /* last chain id in this vcap */
20 	int count; /* number of available addresses */
21 	bool ingress; /* is vcap in the ingress path */
22 } lan966x_vcap_inst_cfg[] = {
23 	{
24 		.vtype = VCAP_TYPE_IS1, /* IS1-0 */
25 		.tgt_inst = 1,
26 		.lookups = LAN966X_IS1_LOOKUPS,
27 		.first_cid = LAN966X_VCAP_CID_IS1_L0,
28 		.last_cid = LAN966X_VCAP_CID_IS1_MAX,
29 		.count = 768,
30 		.ingress = true,
31 	},
32 	{
33 		.vtype = VCAP_TYPE_IS2, /* IS2-0 */
34 		.tgt_inst = 2,
35 		.lookups = LAN966X_IS2_LOOKUPS,
36 		.first_cid = LAN966X_VCAP_CID_IS2_L0,
37 		.last_cid = LAN966X_VCAP_CID_IS2_MAX,
38 		.count = 256,
39 		.ingress = true,
40 	},
41 };
42 
43 struct lan966x_vcap_cmd_cb {
44 	struct lan966x *lan966x;
45 	u32 instance;
46 };
47 
48 static u32 lan966x_vcap_read_update_ctrl(const struct lan966x_vcap_cmd_cb *cb)
49 {
50 	return lan_rd(cb->lan966x, VCAP_UPDATE_CTRL(cb->instance));
51 }
52 
53 static void lan966x_vcap_wait_update(struct lan966x *lan966x, int instance)
54 {
55 	const struct lan966x_vcap_cmd_cb cb = { .lan966x = lan966x,
56 						.instance = instance };
57 	u32 val;
58 
59 	readx_poll_timeout(lan966x_vcap_read_update_ctrl, &cb, val,
60 			   (val & VCAP_UPDATE_CTRL_UPDATE_SHOT) == 0, 10,
61 			   100000);
62 }
63 
64 static void __lan966x_vcap_range_init(struct lan966x *lan966x,
65 				      struct vcap_admin *admin,
66 				      u32 addr,
67 				      u32 count)
68 {
69 	lan_wr(VCAP_MV_CFG_MV_NUM_POS_SET(0) |
70 	       VCAP_MV_CFG_MV_SIZE_SET(count - 1),
71 	       lan966x, VCAP_MV_CFG(admin->tgt_inst));
72 
73 	lan_wr(VCAP_UPDATE_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
74 	       VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS_SET(0) |
75 	       VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS_SET(0) |
76 	       VCAP_UPDATE_CTRL_UPDATE_CNT_DIS_SET(0) |
77 	       VCAP_UPDATE_CTRL_UPDATE_ADDR_SET(addr) |
78 	       VCAP_UPDATE_CTRL_CLEAR_CACHE_SET(true) |
79 	       VCAP_UPDATE_CTRL_UPDATE_SHOT_SET(1),
80 	       lan966x, VCAP_UPDATE_CTRL(admin->tgt_inst));
81 
82 	lan966x_vcap_wait_update(lan966x, admin->tgt_inst);
83 }
84 
85 static int lan966x_vcap_is1_cid_to_lookup(int cid)
86 {
87 	int lookup = 0;
88 
89 	if (cid >= LAN966X_VCAP_CID_IS1_L1 &&
90 	    cid < LAN966X_VCAP_CID_IS1_L2)
91 		lookup = 1;
92 	else if (cid >= LAN966X_VCAP_CID_IS1_L2 &&
93 		 cid < LAN966X_VCAP_CID_IS1_MAX)
94 		lookup = 2;
95 
96 	return lookup;
97 }
98 
99 static int lan966x_vcap_is2_cid_to_lookup(int cid)
100 {
101 	if (cid >= LAN966X_VCAP_CID_IS2_L1 &&
102 	    cid < LAN966X_VCAP_CID_IS2_MAX)
103 		return 1;
104 
105 	return 0;
106 }
107 
108 /* Return the list of keysets for the vcap port configuration */
109 static int
110 lan966x_vcap_is1_get_port_keysets(struct net_device *ndev, int lookup,
111 				  struct vcap_keyset_list *keysetlist,
112 				  u16 l3_proto)
113 {
114 	struct lan966x_port *port = netdev_priv(ndev);
115 	struct lan966x *lan966x = port->lan966x;
116 	u32 val;
117 
118 	val = lan_rd(lan966x, ANA_VCAP_S1_CFG(port->chip_port, lookup));
119 
120 	/* Collect all keysets for the port in a list */
121 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
122 		switch (ANA_VCAP_S1_CFG_KEY_IP4_CFG_GET(val)) {
123 		case VCAP_IS1_PS_IPV4_7TUPLE:
124 			vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE);
125 			break;
126 		case VCAP_IS1_PS_IPV4_5TUPLE_IP4:
127 			vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP4);
128 			break;
129 		case VCAP_IS1_PS_IPV4_NORMAL:
130 			vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL);
131 			break;
132 		}
133 	}
134 
135 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
136 		switch (ANA_VCAP_S1_CFG_KEY_IP6_CFG_GET(val)) {
137 		case VCAP_IS1_PS_IPV6_NORMAL:
138 		case VCAP_IS1_PS_IPV6_NORMAL_IP6:
139 			vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL);
140 			vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_IP6);
141 			break;
142 		case VCAP_IS1_PS_IPV6_5TUPLE_IP6:
143 			vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP6);
144 			break;
145 		case VCAP_IS1_PS_IPV6_7TUPLE:
146 			vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE);
147 			break;
148 		case VCAP_IS1_PS_IPV6_5TUPLE_IP4:
149 			vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP4);
150 			break;
151 		case VCAP_IS1_PS_IPV6_DMAC_VID:
152 			vcap_keyset_list_add(keysetlist, VCAP_KFS_DMAC_VID);
153 			break;
154 		}
155 	}
156 
157 	switch (ANA_VCAP_S1_CFG_KEY_OTHER_CFG_GET(val)) {
158 	case VCAP_IS1_PS_OTHER_7TUPLE:
159 		vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE);
160 		break;
161 	case VCAP_IS1_PS_OTHER_NORMAL:
162 		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL);
163 		break;
164 	}
165 
166 	return 0;
167 }
168 
169 static int
170 lan966x_vcap_is2_get_port_keysets(struct net_device *dev, int lookup,
171 				  struct vcap_keyset_list *keysetlist,
172 				  u16 l3_proto)
173 {
174 	struct lan966x_port *port = netdev_priv(dev);
175 	struct lan966x *lan966x = port->lan966x;
176 	bool found = false;
177 	u32 val;
178 
179 	val = lan_rd(lan966x, ANA_VCAP_S2_CFG(port->chip_port));
180 
181 	/* Collect all keysets for the port in a list */
182 	if (l3_proto == ETH_P_ALL)
183 		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
184 
185 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_SNAP) {
186 		if (ANA_VCAP_S2_CFG_SNAP_DIS_GET(val) & (BIT(0) << lookup))
187 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_LLC);
188 		else
189 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_SNAP);
190 
191 		found = true;
192 	}
193 
194 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_CFM) {
195 		if (ANA_VCAP_S2_CFG_OAM_DIS_GET(val) & (BIT(0) << lookup))
196 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
197 		else
198 			vcap_keyset_list_add(keysetlist, VCAP_KFS_OAM);
199 
200 		found = true;
201 	}
202 
203 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
204 		if (ANA_VCAP_S2_CFG_ARP_DIS_GET(val) & (BIT(0) << lookup))
205 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
206 		else
207 			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
208 
209 		found = true;
210 	}
211 
212 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
213 		if (ANA_VCAP_S2_CFG_IP_OTHER_DIS_GET(val) & (BIT(0) << lookup))
214 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
215 		else
216 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
217 
218 		if (ANA_VCAP_S2_CFG_IP_TCPUDP_DIS_GET(val) & (BIT(0) << lookup))
219 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
220 		else
221 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
222 
223 		found = true;
224 	}
225 
226 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
227 		switch (ANA_VCAP_S2_CFG_IP6_CFG_GET(val) & (0x3 << lookup)) {
228 		case VCAP_IS2_PS_IPV6_TCPUDP_OTHER:
229 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_OTHER);
230 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_TCP_UDP);
231 			break;
232 		case VCAP_IS2_PS_IPV6_STD:
233 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
234 			break;
235 		case VCAP_IS2_PS_IPV6_IP4_TCPUDP_IP4_OTHER:
236 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
237 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
238 			break;
239 		case VCAP_IS2_PS_IPV6_MAC_ETYPE:
240 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
241 			break;
242 		}
243 
244 		found = true;
245 	}
246 
247 	if (!found)
248 		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
249 
250 	return 0;
251 }
252 
253 static enum vcap_keyfield_set
254 lan966x_vcap_validate_keyset(struct net_device *dev,
255 			     struct vcap_admin *admin,
256 			     struct vcap_rule *rule,
257 			     struct vcap_keyset_list *kslist,
258 			     u16 l3_proto)
259 {
260 	struct vcap_keyset_list keysetlist = {};
261 	enum vcap_keyfield_set keysets[10] = {};
262 	int lookup;
263 	int err;
264 
265 	if (!kslist || kslist->cnt == 0)
266 		return VCAP_KFS_NO_VALUE;
267 
268 	keysetlist.max = ARRAY_SIZE(keysets);
269 	keysetlist.keysets = keysets;
270 
271 	switch (admin->vtype) {
272 	case VCAP_TYPE_IS1:
273 		lookup = lan966x_vcap_is1_cid_to_lookup(rule->vcap_chain_id);
274 		err = lan966x_vcap_is1_get_port_keysets(dev, lookup, &keysetlist,
275 							l3_proto);
276 		break;
277 	case VCAP_TYPE_IS2:
278 		lookup = lan966x_vcap_is2_cid_to_lookup(rule->vcap_chain_id);
279 		err = lan966x_vcap_is2_get_port_keysets(dev, lookup, &keysetlist,
280 							l3_proto);
281 		break;
282 	default:
283 		pr_err("vcap type: %s not supported\n",
284 		       lan966x_vcaps[admin->vtype].name);
285 		return VCAP_KFS_NO_VALUE;
286 	}
287 
288 	if (err)
289 		return VCAP_KFS_NO_VALUE;
290 
291 	/* Check if there is a match and return the match */
292 	for (int i = 0; i < kslist->cnt; ++i)
293 		for (int j = 0; j < keysetlist.cnt; ++j)
294 			if (kslist->keysets[i] == keysets[j])
295 				return kslist->keysets[i];
296 
297 	return VCAP_KFS_NO_VALUE;
298 }
299 
300 static bool lan966x_vcap_is2_is_first_chain(struct vcap_rule *rule)
301 {
302 	return (rule->vcap_chain_id >= LAN966X_VCAP_CID_IS2_L0 &&
303 		rule->vcap_chain_id < LAN966X_VCAP_CID_IS2_L1);
304 }
305 
306 static void lan966x_vcap_is1_add_default_fields(struct lan966x_port *port,
307 						struct vcap_admin *admin,
308 						struct vcap_rule *rule)
309 {
310 	u32 value, mask;
311 	u32 lookup;
312 
313 	if (vcap_rule_get_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK,
314 				  &value, &mask))
315 		vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0,
316 				      ~BIT(port->chip_port));
317 
318 	lookup = lan966x_vcap_is1_cid_to_lookup(rule->vcap_chain_id);
319 	vcap_rule_add_key_u32(rule, VCAP_KF_LOOKUP_INDEX, lookup, 0x3);
320 }
321 
322 static void lan966x_vcap_is2_add_default_fields(struct lan966x_port *port,
323 						struct vcap_admin *admin,
324 						struct vcap_rule *rule)
325 {
326 	u32 value, mask;
327 
328 	if (vcap_rule_get_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK,
329 				  &value, &mask))
330 		vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0,
331 				      ~BIT(port->chip_port));
332 
333 	if (lan966x_vcap_is2_is_first_chain(rule))
334 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
335 				      VCAP_BIT_1);
336 	else
337 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
338 				      VCAP_BIT_0);
339 }
340 
341 static void lan966x_vcap_add_default_fields(struct net_device *dev,
342 					    struct vcap_admin *admin,
343 					    struct vcap_rule *rule)
344 {
345 	struct lan966x_port *port = netdev_priv(dev);
346 
347 	switch (admin->vtype) {
348 	case VCAP_TYPE_IS1:
349 		lan966x_vcap_is1_add_default_fields(port, admin, rule);
350 		break;
351 	case VCAP_TYPE_IS2:
352 		lan966x_vcap_is2_add_default_fields(port, admin, rule);
353 		break;
354 	default:
355 		pr_err("vcap type: %s not supported\n",
356 		       lan966x_vcaps[admin->vtype].name);
357 		break;
358 	}
359 }
360 
361 static void lan966x_vcap_cache_erase(struct vcap_admin *admin)
362 {
363 	memset(admin->cache.keystream, 0, STREAMSIZE);
364 	memset(admin->cache.maskstream, 0, STREAMSIZE);
365 	memset(admin->cache.actionstream, 0, STREAMSIZE);
366 	memset(&admin->cache.counter, 0, sizeof(admin->cache.counter));
367 }
368 
369 static void lan966x_vcap_cache_write(struct net_device *dev,
370 				     struct vcap_admin *admin,
371 				     enum vcap_selection sel,
372 				     u32 start,
373 				     u32 count)
374 {
375 	struct lan966x_port *port = netdev_priv(dev);
376 	struct lan966x *lan966x = port->lan966x;
377 	u32 *keystr, *mskstr, *actstr;
378 
379 	keystr = &admin->cache.keystream[start];
380 	mskstr = &admin->cache.maskstream[start];
381 	actstr = &admin->cache.actionstream[start];
382 
383 	switch (sel) {
384 	case VCAP_SEL_ENTRY:
385 		for (int i = 0; i < count; ++i) {
386 			lan_wr(keystr[i] & mskstr[i], lan966x,
387 			       VCAP_ENTRY_DAT(admin->tgt_inst, i));
388 			lan_wr(~mskstr[i], lan966x,
389 			       VCAP_MASK_DAT(admin->tgt_inst, i));
390 		}
391 		break;
392 	case VCAP_SEL_ACTION:
393 		for (int i = 0; i < count; ++i)
394 			lan_wr(actstr[i], lan966x,
395 			       VCAP_ACTION_DAT(admin->tgt_inst, i));
396 		break;
397 	case VCAP_SEL_COUNTER:
398 		admin->cache.sticky = admin->cache.counter > 0;
399 		lan_wr(admin->cache.counter, lan966x,
400 		       VCAP_CNT_DAT(admin->tgt_inst, 0));
401 		break;
402 	default:
403 		break;
404 	}
405 }
406 
407 static void lan966x_vcap_cache_read(struct net_device *dev,
408 				    struct vcap_admin *admin,
409 				    enum vcap_selection sel,
410 				    u32 start,
411 				    u32 count)
412 {
413 	struct lan966x_port *port = netdev_priv(dev);
414 	struct lan966x *lan966x = port->lan966x;
415 	int instance = admin->tgt_inst;
416 	u32 *keystr, *mskstr, *actstr;
417 
418 	keystr = &admin->cache.keystream[start];
419 	mskstr = &admin->cache.maskstream[start];
420 	actstr = &admin->cache.actionstream[start];
421 
422 	if (sel & VCAP_SEL_ENTRY) {
423 		for (int i = 0; i < count; ++i) {
424 			keystr[i] =
425 				lan_rd(lan966x, VCAP_ENTRY_DAT(instance, i));
426 			mskstr[i] =
427 				~lan_rd(lan966x, VCAP_MASK_DAT(instance, i));
428 		}
429 	}
430 
431 	if (sel & VCAP_SEL_ACTION)
432 		for (int i = 0; i < count; ++i)
433 			actstr[i] =
434 				lan_rd(lan966x, VCAP_ACTION_DAT(instance, i));
435 
436 	if (sel & VCAP_SEL_COUNTER) {
437 		admin->cache.counter =
438 			lan_rd(lan966x, VCAP_CNT_DAT(instance, 0));
439 		admin->cache.sticky = admin->cache.counter > 0;
440 	}
441 }
442 
443 static void lan966x_vcap_range_init(struct net_device *dev,
444 				    struct vcap_admin *admin,
445 				    u32 addr,
446 				    u32 count)
447 {
448 	struct lan966x_port *port = netdev_priv(dev);
449 	struct lan966x *lan966x = port->lan966x;
450 
451 	__lan966x_vcap_range_init(lan966x, admin, addr, count);
452 }
453 
454 static void lan966x_vcap_update(struct net_device *dev,
455 				struct vcap_admin *admin,
456 				enum vcap_command cmd,
457 				enum vcap_selection sel,
458 				u32 addr)
459 {
460 	struct lan966x_port *port = netdev_priv(dev);
461 	struct lan966x *lan966x = port->lan966x;
462 	bool clear;
463 
464 	clear = (cmd == VCAP_CMD_INITIALIZE);
465 
466 	lan_wr(VCAP_MV_CFG_MV_NUM_POS_SET(0) |
467 	       VCAP_MV_CFG_MV_SIZE_SET(0),
468 	       lan966x, VCAP_MV_CFG(admin->tgt_inst));
469 
470 	lan_wr(VCAP_UPDATE_CTRL_UPDATE_CMD_SET(cmd) |
471 	       VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
472 	       VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
473 	       VCAP_UPDATE_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
474 	       VCAP_UPDATE_CTRL_UPDATE_ADDR_SET(addr) |
475 	       VCAP_UPDATE_CTRL_CLEAR_CACHE_SET(clear) |
476 	       VCAP_UPDATE_CTRL_UPDATE_SHOT,
477 	       lan966x, VCAP_UPDATE_CTRL(admin->tgt_inst));
478 
479 	lan966x_vcap_wait_update(lan966x, admin->tgt_inst);
480 }
481 
482 static void lan966x_vcap_move(struct net_device *dev,
483 			      struct vcap_admin *admin,
484 			      u32 addr, int offset, int count)
485 {
486 	struct lan966x_port *port = netdev_priv(dev);
487 	struct lan966x *lan966x = port->lan966x;
488 	enum vcap_command cmd;
489 	u16 mv_num_pos;
490 	u16 mv_size;
491 
492 	mv_size = count - 1;
493 	if (offset > 0) {
494 		mv_num_pos = offset - 1;
495 		cmd = VCAP_CMD_MOVE_DOWN;
496 	} else {
497 		mv_num_pos = -offset - 1;
498 		cmd = VCAP_CMD_MOVE_UP;
499 	}
500 
501 	lan_wr(VCAP_MV_CFG_MV_NUM_POS_SET(mv_num_pos) |
502 	       VCAP_MV_CFG_MV_SIZE_SET(mv_size),
503 	       lan966x, VCAP_MV_CFG(admin->tgt_inst));
504 
505 	lan_wr(VCAP_UPDATE_CTRL_UPDATE_CMD_SET(cmd) |
506 	       VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS_SET(0) |
507 	       VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS_SET(0) |
508 	       VCAP_UPDATE_CTRL_UPDATE_CNT_DIS_SET(0) |
509 	       VCAP_UPDATE_CTRL_UPDATE_ADDR_SET(addr) |
510 	       VCAP_UPDATE_CTRL_CLEAR_CACHE_SET(false) |
511 	       VCAP_UPDATE_CTRL_UPDATE_SHOT,
512 	       lan966x, VCAP_UPDATE_CTRL(admin->tgt_inst));
513 
514 	lan966x_vcap_wait_update(lan966x, admin->tgt_inst);
515 }
516 
517 static struct vcap_operations lan966x_vcap_ops = {
518 	.validate_keyset = lan966x_vcap_validate_keyset,
519 	.add_default_fields = lan966x_vcap_add_default_fields,
520 	.cache_erase = lan966x_vcap_cache_erase,
521 	.cache_write = lan966x_vcap_cache_write,
522 	.cache_read = lan966x_vcap_cache_read,
523 	.init = lan966x_vcap_range_init,
524 	.update = lan966x_vcap_update,
525 	.move = lan966x_vcap_move,
526 	.port_info = lan966x_vcap_port_info,
527 };
528 
529 static void lan966x_vcap_admin_free(struct vcap_admin *admin)
530 {
531 	if (!admin)
532 		return;
533 
534 	kfree(admin->cache.keystream);
535 	kfree(admin->cache.maskstream);
536 	kfree(admin->cache.actionstream);
537 	mutex_destroy(&admin->lock);
538 	kfree(admin);
539 }
540 
541 static struct vcap_admin *
542 lan966x_vcap_admin_alloc(struct lan966x *lan966x, struct vcap_control *ctrl,
543 			 const struct lan966x_vcap_inst *cfg)
544 {
545 	struct vcap_admin *admin;
546 
547 	admin = kzalloc(sizeof(*admin), GFP_KERNEL);
548 	if (!admin)
549 		return ERR_PTR(-ENOMEM);
550 
551 	mutex_init(&admin->lock);
552 	INIT_LIST_HEAD(&admin->list);
553 	INIT_LIST_HEAD(&admin->rules);
554 	INIT_LIST_HEAD(&admin->enabled);
555 
556 	admin->vtype = cfg->vtype;
557 	admin->vinst = 0;
558 	admin->ingress = cfg->ingress;
559 	admin->w32be = true;
560 	admin->tgt_inst = cfg->tgt_inst;
561 
562 	admin->lookups = cfg->lookups;
563 	admin->lookups_per_instance = cfg->lookups;
564 
565 	admin->first_cid = cfg->first_cid;
566 	admin->last_cid = cfg->last_cid;
567 
568 	admin->cache.keystream = kzalloc(STREAMSIZE, GFP_KERNEL);
569 	admin->cache.maskstream = kzalloc(STREAMSIZE, GFP_KERNEL);
570 	admin->cache.actionstream = kzalloc(STREAMSIZE, GFP_KERNEL);
571 	if (!admin->cache.keystream ||
572 	    !admin->cache.maskstream ||
573 	    !admin->cache.actionstream) {
574 		lan966x_vcap_admin_free(admin);
575 		return ERR_PTR(-ENOMEM);
576 	}
577 
578 	return admin;
579 }
580 
581 static void lan966x_vcap_block_init(struct lan966x *lan966x,
582 				    struct vcap_admin *admin,
583 				    struct lan966x_vcap_inst *cfg)
584 {
585 	admin->first_valid_addr = 0;
586 	admin->last_used_addr = cfg->count;
587 	admin->last_valid_addr = cfg->count - 1;
588 
589 	lan_wr(VCAP_CORE_IDX_CORE_IDX_SET(0),
590 	       lan966x, VCAP_CORE_IDX(admin->tgt_inst));
591 	lan_wr(VCAP_CORE_MAP_CORE_MAP_SET(1),
592 	       lan966x, VCAP_CORE_MAP(admin->tgt_inst));
593 
594 	__lan966x_vcap_range_init(lan966x, admin, admin->first_valid_addr,
595 				  admin->last_valid_addr -
596 					admin->first_valid_addr);
597 }
598 
599 static void lan966x_vcap_port_key_deselection(struct lan966x *lan966x,
600 					      struct vcap_admin *admin)
601 {
602 	u32 val;
603 
604 	switch (admin->vtype) {
605 	case VCAP_TYPE_IS1:
606 		val = ANA_VCAP_S1_CFG_KEY_IP6_CFG_SET(VCAP_IS1_PS_IPV6_5TUPLE_IP6) |
607 		      ANA_VCAP_S1_CFG_KEY_IP4_CFG_SET(VCAP_IS1_PS_IPV4_5TUPLE_IP4) |
608 		      ANA_VCAP_S1_CFG_KEY_OTHER_CFG_SET(VCAP_IS1_PS_OTHER_NORMAL);
609 
610 		for (int p = 0; p < lan966x->num_phys_ports; ++p) {
611 			if (!lan966x->ports[p])
612 				continue;
613 
614 			for (int l = 0; l < LAN966X_IS1_LOOKUPS; ++l)
615 				lan_wr(val, lan966x, ANA_VCAP_S1_CFG(p, l));
616 
617 			lan_rmw(ANA_VCAP_CFG_S1_ENA_SET(true),
618 				ANA_VCAP_CFG_S1_ENA, lan966x,
619 				ANA_VCAP_CFG(p));
620 		}
621 
622 		break;
623 	case VCAP_TYPE_IS2:
624 		for (int p = 0; p < lan966x->num_phys_ports; ++p)
625 			lan_wr(0, lan966x, ANA_VCAP_S2_CFG(p));
626 
627 		break;
628 	default:
629 		pr_err("vcap type: %s not supported\n",
630 		       lan966x_vcaps[admin->vtype].name);
631 		break;
632 	}
633 }
634 
635 int lan966x_vcap_init(struct lan966x *lan966x)
636 {
637 	struct lan966x_vcap_inst *cfg;
638 	struct vcap_control *ctrl;
639 	struct vcap_admin *admin;
640 	struct dentry *dir;
641 
642 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
643 	if (!ctrl)
644 		return -ENOMEM;
645 
646 	ctrl->vcaps = lan966x_vcaps;
647 	ctrl->stats = &lan966x_vcap_stats;
648 	ctrl->ops = &lan966x_vcap_ops;
649 
650 	INIT_LIST_HEAD(&ctrl->list);
651 	for (int i = 0; i < ARRAY_SIZE(lan966x_vcap_inst_cfg); ++i) {
652 		cfg = &lan966x_vcap_inst_cfg[i];
653 
654 		admin = lan966x_vcap_admin_alloc(lan966x, ctrl, cfg);
655 		if (IS_ERR(admin))
656 			return PTR_ERR(admin);
657 
658 		lan966x_vcap_block_init(lan966x, admin, cfg);
659 		lan966x_vcap_port_key_deselection(lan966x, admin);
660 
661 		list_add_tail(&admin->list, &ctrl->list);
662 	}
663 
664 	dir = vcap_debugfs(lan966x->dev, lan966x->debugfs_root, ctrl);
665 	for (int p = 0; p < lan966x->num_phys_ports; ++p) {
666 		if (lan966x->ports[p]) {
667 			vcap_port_debugfs(lan966x->dev, dir, ctrl,
668 					  lan966x->ports[p]->dev);
669 
670 			lan_rmw(ANA_VCAP_S2_CFG_ENA_SET(true),
671 				ANA_VCAP_S2_CFG_ENA, lan966x,
672 				ANA_VCAP_S2_CFG(lan966x->ports[p]->chip_port));
673 
674 			lan_rmw(ANA_VCAP_CFG_S1_ENA_SET(true),
675 				ANA_VCAP_CFG_S1_ENA, lan966x,
676 				ANA_VCAP_CFG(lan966x->ports[p]->chip_port));
677 		}
678 	}
679 
680 	lan966x->vcap_ctrl = ctrl;
681 
682 	return 0;
683 }
684 
685 void lan966x_vcap_deinit(struct lan966x *lan966x)
686 {
687 	struct vcap_admin *admin, *admin_next;
688 	struct vcap_control *ctrl;
689 
690 	ctrl = lan966x->vcap_ctrl;
691 	if (!ctrl)
692 		return;
693 
694 	list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) {
695 		lan966x_vcap_port_key_deselection(lan966x, admin);
696 		vcap_del_rules(ctrl, admin);
697 		list_del(&admin->list);
698 		lan966x_vcap_admin_free(admin);
699 	}
700 
701 	kfree(ctrl);
702 }
703