1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries.
3  * Microchip VCAP API kunit test suite
4  */
5 
6 #include <kunit/test.h>
7 #include "vcap_api.h"
8 #include "vcap_api_client.h"
9 #include "vcap_model_kunit.h"
10 
11 /* First we have the test infrastructure that emulates the platform
12  * implementation
13  */
14 #define TEST_BUF_CNT 100
15 #define TEST_BUF_SZ  350
16 #define STREAMWSIZE 64
17 
18 static u32 test_updateaddr[STREAMWSIZE] = {};
19 static int test_updateaddridx;
20 static int test_cache_erase_count;
21 static u32 test_init_start;
22 static u32 test_init_count;
23 static u32 test_hw_counter_id;
24 static struct vcap_cache_data test_hw_cache;
25 
26 /* Callback used by the VCAP API */
27 static enum vcap_keyfield_set test_val_keyset(struct net_device *ndev,
28 					      struct vcap_admin *admin,
29 					      struct vcap_rule *rule,
30 					      struct vcap_keyset_list *kslist,
31 					      u16 l3_proto)
32 {
33 	int idx;
34 
35 	if (kslist->cnt > 0) {
36 		switch (admin->vtype) {
37 		case VCAP_TYPE_IS0:
38 			for (idx = 0; idx < kslist->cnt; idx++) {
39 				if (kslist->keysets[idx] == VCAP_KFS_ETAG)
40 					return kslist->keysets[idx];
41 				if (kslist->keysets[idx] == VCAP_KFS_PURE_5TUPLE_IP4)
42 					return kslist->keysets[idx];
43 				if (kslist->keysets[idx] == VCAP_KFS_NORMAL_5TUPLE_IP4)
44 					return kslist->keysets[idx];
45 				if (kslist->keysets[idx] == VCAP_KFS_NORMAL_7TUPLE)
46 					return kslist->keysets[idx];
47 			}
48 			break;
49 		case VCAP_TYPE_IS2:
50 			for (idx = 0; idx < kslist->cnt; idx++) {
51 				if (kslist->keysets[idx] == VCAP_KFS_MAC_ETYPE)
52 					return kslist->keysets[idx];
53 				if (kslist->keysets[idx] == VCAP_KFS_ARP)
54 					return kslist->keysets[idx];
55 				if (kslist->keysets[idx] == VCAP_KFS_IP_7TUPLE)
56 					return kslist->keysets[idx];
57 			}
58 			break;
59 		default:
60 			pr_info("%s:%d: no validation for VCAP %d\n",
61 				__func__, __LINE__, admin->vtype);
62 			break;
63 		}
64 	}
65 	return -EINVAL;
66 }
67 
68 /* Callback used by the VCAP API */
69 static void test_add_def_fields(struct net_device *ndev,
70 				struct vcap_admin *admin,
71 				struct vcap_rule *rule)
72 {
73 	if (admin->vinst == 0 || admin->vinst == 2)
74 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_1);
75 	else
76 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_0);
77 }
78 
79 /* Callback used by the VCAP API */
80 static void test_cache_erase(struct vcap_admin *admin)
81 {
82 	if (test_cache_erase_count) {
83 		memset(admin->cache.keystream, 0, test_cache_erase_count);
84 		memset(admin->cache.maskstream, 0, test_cache_erase_count);
85 		memset(admin->cache.actionstream, 0, test_cache_erase_count);
86 		test_cache_erase_count = 0;
87 	}
88 }
89 
90 /* Callback used by the VCAP API */
91 static void test_cache_init(struct net_device *ndev, struct vcap_admin *admin,
92 			    u32 start, u32 count)
93 {
94 	test_init_start = start;
95 	test_init_count = count;
96 }
97 
98 /* Callback used by the VCAP API */
99 static void test_cache_read(struct net_device *ndev, struct vcap_admin *admin,
100 			    enum vcap_selection sel, u32 start, u32 count)
101 {
102 	u32 *keystr, *mskstr, *actstr;
103 	int idx;
104 
105 	pr_debug("%s:%d: %d %d\n", __func__, __LINE__, start, count);
106 	switch (sel) {
107 	case VCAP_SEL_ENTRY:
108 		keystr = &admin->cache.keystream[start];
109 		mskstr = &admin->cache.maskstream[start];
110 		for (idx = 0; idx < count; ++idx) {
111 			pr_debug("%s:%d: keydata[%02d]: 0x%08x\n", __func__,
112 				 __LINE__, start + idx, keystr[idx]);
113 		}
114 		for (idx = 0; idx < count; ++idx) {
115 			/* Invert the mask before decoding starts */
116 			mskstr[idx] = ~mskstr[idx];
117 			pr_debug("%s:%d: mskdata[%02d]: 0x%08x\n", __func__,
118 				 __LINE__, start + idx, mskstr[idx]);
119 		}
120 		break;
121 	case VCAP_SEL_ACTION:
122 		actstr = &admin->cache.actionstream[start];
123 		for (idx = 0; idx < count; ++idx) {
124 			pr_debug("%s:%d: actdata[%02d]: 0x%08x\n", __func__,
125 				 __LINE__, start + idx, actstr[idx]);
126 		}
127 		break;
128 	case VCAP_SEL_COUNTER:
129 		pr_debug("%s:%d\n", __func__, __LINE__);
130 		test_hw_counter_id = start;
131 		admin->cache.counter = test_hw_cache.counter;
132 		admin->cache.sticky = test_hw_cache.sticky;
133 		break;
134 	case VCAP_SEL_ALL:
135 		pr_debug("%s:%d\n", __func__, __LINE__);
136 		break;
137 	}
138 }
139 
140 /* Callback used by the VCAP API */
141 static void test_cache_write(struct net_device *ndev, struct vcap_admin *admin,
142 			     enum vcap_selection sel, u32 start, u32 count)
143 {
144 	u32 *keystr, *mskstr, *actstr;
145 	int idx;
146 
147 	switch (sel) {
148 	case VCAP_SEL_ENTRY:
149 		keystr = &admin->cache.keystream[start];
150 		mskstr = &admin->cache.maskstream[start];
151 		for (idx = 0; idx < count; ++idx) {
152 			pr_debug("%s:%d: keydata[%02d]: 0x%08x\n", __func__,
153 				 __LINE__, start + idx, keystr[idx]);
154 		}
155 		for (idx = 0; idx < count; ++idx) {
156 			/* Invert the mask before encoding starts */
157 			mskstr[idx] = ~mskstr[idx];
158 			pr_debug("%s:%d: mskdata[%02d]: 0x%08x\n", __func__,
159 				 __LINE__, start + idx, mskstr[idx]);
160 		}
161 		break;
162 	case VCAP_SEL_ACTION:
163 		actstr = &admin->cache.actionstream[start];
164 		for (idx = 0; idx < count; ++idx) {
165 			pr_debug("%s:%d: actdata[%02d]: 0x%08x\n", __func__,
166 				 __LINE__, start + idx, actstr[idx]);
167 		}
168 		break;
169 	case VCAP_SEL_COUNTER:
170 		pr_debug("%s:%d\n", __func__, __LINE__);
171 		test_hw_counter_id = start;
172 		test_hw_cache.counter = admin->cache.counter;
173 		test_hw_cache.sticky = admin->cache.sticky;
174 		break;
175 	case VCAP_SEL_ALL:
176 		pr_err("%s:%d: cannot write all streams at once\n",
177 		       __func__, __LINE__);
178 		break;
179 	}
180 }
181 
182 /* Callback used by the VCAP API */
183 static void test_cache_update(struct net_device *ndev, struct vcap_admin *admin,
184 			      enum vcap_command cmd,
185 			      enum vcap_selection sel, u32 addr)
186 {
187 	if (test_updateaddridx < ARRAY_SIZE(test_updateaddr))
188 		test_updateaddr[test_updateaddridx] = addr;
189 	else
190 		pr_err("%s:%d: overflow: %d\n", __func__, __LINE__, test_updateaddridx);
191 	test_updateaddridx++;
192 }
193 
194 static void test_cache_move(struct net_device *ndev, struct vcap_admin *admin,
195 			    u32 addr, int offset, int count)
196 {
197 }
198 
199 /* Provide port information via a callback interface */
200 static int vcap_test_port_info(struct net_device *ndev, enum vcap_type vtype,
201 			       int (*pf)(void *out, int arg, const char *fmt, ...),
202 			       void *out, int arg)
203 {
204 	return 0;
205 }
206 
207 static struct vcap_operations test_callbacks = {
208 	.validate_keyset = test_val_keyset,
209 	.add_default_fields = test_add_def_fields,
210 	.cache_erase = test_cache_erase,
211 	.cache_write = test_cache_write,
212 	.cache_read = test_cache_read,
213 	.init = test_cache_init,
214 	.update = test_cache_update,
215 	.move = test_cache_move,
216 	.port_info = vcap_test_port_info,
217 };
218 
219 static struct vcap_control test_vctrl = {
220 	.vcaps = kunit_test_vcaps,
221 	.stats = &kunit_test_vcap_stats,
222 	.ops = &test_callbacks,
223 };
224 
225 static void vcap_test_api_init(struct vcap_admin *admin)
226 {
227 	/* Initialize the shared objects */
228 	INIT_LIST_HEAD(&test_vctrl.list);
229 	INIT_LIST_HEAD(&admin->list);
230 	INIT_LIST_HEAD(&admin->rules);
231 	list_add_tail(&admin->list, &test_vctrl.list);
232 	memset(test_updateaddr, 0, sizeof(test_updateaddr));
233 	test_updateaddridx = 0;
234 }
235 
236 /* Define the test cases. */
237 
238 static void vcap_api_set_bit_1_test(struct kunit *test)
239 {
240 	struct vcap_stream_iter iter = {
241 		.offset = 35,
242 		.sw_width = 52,
243 		.reg_idx = 1,
244 		.reg_bitpos = 20,
245 		.tg = 0
246 	};
247 	u32 stream[2] = {0};
248 
249 	vcap_set_bit(stream, &iter, 1);
250 
251 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]);
252 	KUNIT_EXPECT_EQ(test, (u32)BIT(20), stream[1]);
253 }
254 
255 static void vcap_api_set_bit_0_test(struct kunit *test)
256 {
257 	struct vcap_stream_iter iter = {
258 		.offset = 35,
259 		.sw_width = 52,
260 		.reg_idx = 2,
261 		.reg_bitpos = 11,
262 		.tg = 0
263 	};
264 	u32 stream[3] = {~0, ~0, ~0};
265 
266 	vcap_set_bit(stream, &iter, 0);
267 
268 	KUNIT_EXPECT_EQ(test, (u32)~0, stream[0]);
269 	KUNIT_EXPECT_EQ(test, (u32)~0, stream[1]);
270 	KUNIT_EXPECT_EQ(test, (u32)~BIT(11), stream[2]);
271 }
272 
273 static void vcap_api_iterator_init_test(struct kunit *test)
274 {
275 	struct vcap_stream_iter iter;
276 	struct vcap_typegroup typegroups[] = {
277 		{ .offset = 0, .width = 2, .value = 2, },
278 		{ .offset = 156, .width = 1, .value = 0, },
279 		{ .offset = 0, .width = 0, .value = 0, },
280 	};
281 	struct vcap_typegroup typegroups2[] = {
282 		{ .offset = 0, .width = 3, .value = 4, },
283 		{ .offset = 49, .width = 2, .value = 0, },
284 		{ .offset = 98, .width = 2, .value = 0, },
285 	};
286 
287 	vcap_iter_init(&iter, 52, typegroups, 86);
288 
289 	KUNIT_EXPECT_EQ(test, 52, iter.sw_width);
290 	KUNIT_EXPECT_EQ(test, 86 + 2, iter.offset);
291 	KUNIT_EXPECT_EQ(test, 3, iter.reg_idx);
292 	KUNIT_EXPECT_EQ(test, 4, iter.reg_bitpos);
293 
294 	vcap_iter_init(&iter, 49, typegroups2, 134);
295 
296 	KUNIT_EXPECT_EQ(test, 49, iter.sw_width);
297 	KUNIT_EXPECT_EQ(test, 134 + 7, iter.offset);
298 	KUNIT_EXPECT_EQ(test, 5, iter.reg_idx);
299 	KUNIT_EXPECT_EQ(test, 11, iter.reg_bitpos);
300 }
301 
302 static void vcap_api_iterator_next_test(struct kunit *test)
303 {
304 	struct vcap_stream_iter iter;
305 	struct vcap_typegroup typegroups[] = {
306 		{ .offset = 0, .width = 4, .value = 8, },
307 		{ .offset = 49, .width = 1, .value = 0, },
308 		{ .offset = 98, .width = 2, .value = 0, },
309 		{ .offset = 147, .width = 3, .value = 0, },
310 		{ .offset = 196, .width = 2, .value = 0, },
311 		{ .offset = 245, .width = 1, .value = 0, },
312 	};
313 	int idx;
314 
315 	vcap_iter_init(&iter, 49, typegroups, 86);
316 
317 	KUNIT_EXPECT_EQ(test, 49, iter.sw_width);
318 	KUNIT_EXPECT_EQ(test, 86 + 5, iter.offset);
319 	KUNIT_EXPECT_EQ(test, 3, iter.reg_idx);
320 	KUNIT_EXPECT_EQ(test, 10, iter.reg_bitpos);
321 
322 	vcap_iter_next(&iter);
323 
324 	KUNIT_EXPECT_EQ(test, 91 + 1, iter.offset);
325 	KUNIT_EXPECT_EQ(test, 3, iter.reg_idx);
326 	KUNIT_EXPECT_EQ(test, 11, iter.reg_bitpos);
327 
328 	for (idx = 0; idx < 6; idx++)
329 		vcap_iter_next(&iter);
330 
331 	KUNIT_EXPECT_EQ(test, 92 + 6 + 2, iter.offset);
332 	KUNIT_EXPECT_EQ(test, 4, iter.reg_idx);
333 	KUNIT_EXPECT_EQ(test, 2, iter.reg_bitpos);
334 }
335 
336 static void vcap_api_encode_typegroups_test(struct kunit *test)
337 {
338 	u32 stream[12] = {0};
339 	struct vcap_typegroup typegroups[] = {
340 		{ .offset = 0, .width = 4, .value = 8, },
341 		{ .offset = 49, .width = 1, .value = 1, },
342 		{ .offset = 98, .width = 2, .value = 3, },
343 		{ .offset = 147, .width = 3, .value = 5, },
344 		{ .offset = 196, .width = 2, .value = 2, },
345 		{ .offset = 245, .width = 5, .value = 27, },
346 		{ .offset = 0, .width = 0, .value = 0, },
347 	};
348 
349 	vcap_encode_typegroups(stream, 49, typegroups, false);
350 
351 	KUNIT_EXPECT_EQ(test, (u32)0x8, stream[0]);
352 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[1]);
353 	KUNIT_EXPECT_EQ(test, (u32)0x1, stream[2]);
354 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[3]);
355 	KUNIT_EXPECT_EQ(test, (u32)0x3, stream[4]);
356 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[5]);
357 	KUNIT_EXPECT_EQ(test, (u32)0x5, stream[6]);
358 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[7]);
359 	KUNIT_EXPECT_EQ(test, (u32)0x2, stream[8]);
360 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[9]);
361 	KUNIT_EXPECT_EQ(test, (u32)27, stream[10]);
362 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[11]);
363 }
364 
365 static void vcap_api_encode_bit_test(struct kunit *test)
366 {
367 	struct vcap_stream_iter iter;
368 	u32 stream[4] = {0};
369 	struct vcap_typegroup typegroups[] = {
370 		{ .offset = 0, .width = 4, .value = 8, },
371 		{ .offset = 49, .width = 1, .value = 1, },
372 		{ .offset = 98, .width = 2, .value = 3, },
373 		{ .offset = 147, .width = 3, .value = 5, },
374 		{ .offset = 196, .width = 2, .value = 2, },
375 		{ .offset = 245, .width = 1, .value = 0, },
376 	};
377 
378 	vcap_iter_init(&iter, 49, typegroups, 44);
379 
380 	KUNIT_EXPECT_EQ(test, 48, iter.offset);
381 	KUNIT_EXPECT_EQ(test, 1, iter.reg_idx);
382 	KUNIT_EXPECT_EQ(test, 16, iter.reg_bitpos);
383 
384 	vcap_encode_bit(stream, &iter, 1);
385 
386 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]);
387 	KUNIT_EXPECT_EQ(test, (u32)BIT(16), stream[1]);
388 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[2]);
389 }
390 
391 static void vcap_api_encode_field_test(struct kunit *test)
392 {
393 	struct vcap_stream_iter iter;
394 	u32 stream[16] = {0};
395 	struct vcap_typegroup typegroups[] = {
396 		{ .offset = 0, .width = 4, .value = 8, },
397 		{ .offset = 49, .width = 1, .value = 1, },
398 		{ .offset = 98, .width = 2, .value = 3, },
399 		{ .offset = 147, .width = 3, .value = 5, },
400 		{ .offset = 196, .width = 2, .value = 2, },
401 		{ .offset = 245, .width = 5, .value = 27, },
402 		{ .offset = 0, .width = 0, .value = 0, },
403 	};
404 	struct vcap_field rf = {
405 		.type = VCAP_FIELD_U32,
406 		.offset = 86,
407 		.width = 4,
408 	};
409 	u8 value[] = {0x5};
410 
411 	vcap_iter_init(&iter, 49, typegroups, rf.offset);
412 
413 	KUNIT_EXPECT_EQ(test, 91, iter.offset);
414 	KUNIT_EXPECT_EQ(test, 3, iter.reg_idx);
415 	KUNIT_EXPECT_EQ(test, 10, iter.reg_bitpos);
416 
417 	vcap_encode_field(stream, &iter, rf.width, value);
418 
419 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]);
420 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[1]);
421 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[2]);
422 	KUNIT_EXPECT_EQ(test, (u32)(0x5 << 10), stream[3]);
423 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[4]);
424 
425 	vcap_encode_typegroups(stream, 49, typegroups, false);
426 
427 	KUNIT_EXPECT_EQ(test, (u32)0x8, stream[0]);
428 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[1]);
429 	KUNIT_EXPECT_EQ(test, (u32)0x1, stream[2]);
430 	KUNIT_EXPECT_EQ(test, (u32)(0x5 << 10), stream[3]);
431 	KUNIT_EXPECT_EQ(test, (u32)0x3, stream[4]);
432 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[5]);
433 	KUNIT_EXPECT_EQ(test, (u32)0x5, stream[6]);
434 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[7]);
435 	KUNIT_EXPECT_EQ(test, (u32)0x2, stream[8]);
436 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[9]);
437 	KUNIT_EXPECT_EQ(test, (u32)27, stream[10]);
438 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[11]);
439 }
440 
441 /* In this testcase the subword is smaller than a register */
442 static void vcap_api_encode_short_field_test(struct kunit *test)
443 {
444 	struct vcap_stream_iter iter;
445 	int sw_width = 21;
446 	u32 stream[6] = {0};
447 	struct vcap_typegroup tgt[] = {
448 		{ .offset = 0, .width = 3, .value = 7, },
449 		{ .offset = 21, .width = 2, .value = 3, },
450 		{ .offset = 42, .width = 1, .value = 1, },
451 		{ .offset = 0, .width = 0, .value = 0, },
452 	};
453 	struct vcap_field rf = {
454 		.type = VCAP_FIELD_U32,
455 		.offset = 25,
456 		.width = 4,
457 	};
458 	u8 value[] = {0x5};
459 
460 	vcap_iter_init(&iter, sw_width, tgt, rf.offset);
461 
462 	KUNIT_EXPECT_EQ(test, 1, iter.regs_per_sw);
463 	KUNIT_EXPECT_EQ(test, 21, iter.sw_width);
464 	KUNIT_EXPECT_EQ(test, 25 + 3 + 2, iter.offset);
465 	KUNIT_EXPECT_EQ(test, 1, iter.reg_idx);
466 	KUNIT_EXPECT_EQ(test, 25 + 3 + 2 - sw_width, iter.reg_bitpos);
467 
468 	vcap_encode_field(stream, &iter, rf.width, value);
469 
470 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]);
471 	KUNIT_EXPECT_EQ(test, (u32)(0x5 << (25 + 3 + 2 - sw_width)), stream[1]);
472 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[2]);
473 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[3]);
474 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[4]);
475 	KUNIT_EXPECT_EQ(test, (u32)0x0, stream[5]);
476 
477 	vcap_encode_typegroups(stream, sw_width, tgt, false);
478 
479 	KUNIT_EXPECT_EQ(test, (u32)7, stream[0]);
480 	KUNIT_EXPECT_EQ(test, (u32)((0x5 << (25 + 3 + 2 - sw_width)) + 3), stream[1]);
481 	KUNIT_EXPECT_EQ(test, (u32)1, stream[2]);
482 	KUNIT_EXPECT_EQ(test, (u32)0, stream[3]);
483 	KUNIT_EXPECT_EQ(test, (u32)0, stream[4]);
484 	KUNIT_EXPECT_EQ(test, (u32)0, stream[5]);
485 }
486 
487 static void vcap_api_encode_keyfield_test(struct kunit *test)
488 {
489 	u32 keywords[16] = {0};
490 	u32 maskwords[16] = {0};
491 	struct vcap_admin admin = {
492 		.vtype = VCAP_TYPE_IS2,
493 		.cache = {
494 			.keystream = keywords,
495 			.maskstream = maskwords,
496 			.actionstream = keywords,
497 		},
498 	};
499 	struct vcap_rule_internal rule = {
500 		.admin = &admin,
501 		.data = {
502 			.keyset = VCAP_KFS_MAC_ETYPE,
503 		},
504 		.vctrl = &test_vctrl,
505 	};
506 	struct vcap_client_keyfield ckf = {
507 		.ctrl.list = {},
508 		.ctrl.key = VCAP_KF_ISDX_CLS,
509 		.ctrl.type = VCAP_FIELD_U32,
510 		.data.u32.value = 0xeef014a1,
511 		.data.u32.mask = 0xfff,
512 	};
513 	struct vcap_field rf = {
514 		.type = VCAP_FIELD_U32,
515 		.offset = 56,
516 		.width = 12,
517 	};
518 	struct vcap_typegroup tgt[] = {
519 		{ .offset = 0, .width = 2, .value = 2, },
520 		{ .offset = 156, .width = 1, .value = 1, },
521 		{ .offset = 0, .width = 0, .value = 0, },
522 	};
523 
524 	vcap_test_api_init(&admin);
525 	vcap_encode_keyfield(&rule, &ckf, &rf, tgt);
526 
527 	/* Key */
528 	KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[0]);
529 	KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[1]);
530 	KUNIT_EXPECT_EQ(test, (u32)(0x04a1 << 6), keywords[2]);
531 	KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[3]);
532 	KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[4]);
533 	KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[5]);
534 	KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[6]);
535 
536 	/* Mask */
537 	KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[0]);
538 	KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[1]);
539 	KUNIT_EXPECT_EQ(test, (u32)(0x0fff << 6), maskwords[2]);
540 	KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[3]);
541 	KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[4]);
542 	KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[5]);
543 	KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[6]);
544 }
545 
546 static void vcap_api_encode_max_keyfield_test(struct kunit *test)
547 {
548 	int idx;
549 	u32 keywords[6] = {0};
550 	u32 maskwords[6] = {0};
551 	struct vcap_admin admin = {
552 		.vtype = VCAP_TYPE_IS2,
553 		/* IS2 sw_width = 52 bit */
554 		.cache = {
555 			.keystream = keywords,
556 			.maskstream = maskwords,
557 			.actionstream = keywords,
558 		},
559 	};
560 	struct vcap_rule_internal rule = {
561 		.admin = &admin,
562 		.data = {
563 			.keyset = VCAP_KFS_IP_7TUPLE,
564 		},
565 		.vctrl = &test_vctrl,
566 	};
567 	struct vcap_client_keyfield ckf = {
568 		.ctrl.list = {},
569 		.ctrl.key = VCAP_KF_L3_IP6_DIP,
570 		.ctrl.type = VCAP_FIELD_U128,
571 		.data.u128.value = { 0xa1, 0xa2, 0xa3, 0xa4, 0, 0, 0x43, 0,
572 			0, 0, 0, 0, 0, 0, 0x78, 0x8e, },
573 		.data.u128.mask =  { 0xff, 0xff, 0xff, 0xff, 0, 0, 0xff, 0,
574 			0, 0, 0, 0, 0, 0, 0xff, 0xff },
575 	};
576 	struct vcap_field rf = {
577 		.type = VCAP_FIELD_U128,
578 		.offset = 0,
579 		.width = 128,
580 	};
581 	struct vcap_typegroup tgt[] = {
582 		{ .offset = 0, .width = 2, .value = 2, },
583 		{ .offset = 156, .width = 1, .value = 1, },
584 		{ .offset = 0, .width = 0, .value = 0, },
585 	};
586 	u32 keyres[] = {
587 		0x928e8a84,
588 		0x000c0002,
589 		0x00000010,
590 		0x00000000,
591 		0x0239e000,
592 		0x00000000,
593 	};
594 	u32 mskres[] = {
595 		0xfffffffc,
596 		0x000c0003,
597 		0x0000003f,
598 		0x00000000,
599 		0x03fffc00,
600 		0x00000000,
601 	};
602 
603 	vcap_encode_keyfield(&rule, &ckf, &rf, tgt);
604 
605 	/* Key */
606 	for (idx = 0; idx < ARRAY_SIZE(keyres); ++idx)
607 		KUNIT_EXPECT_EQ(test, keyres[idx], keywords[idx]);
608 	/* Mask */
609 	for (idx = 0; idx < ARRAY_SIZE(mskres); ++idx)
610 		KUNIT_EXPECT_EQ(test, mskres[idx], maskwords[idx]);
611 }
612 
613 static void vcap_api_encode_actionfield_test(struct kunit *test)
614 {
615 	u32 actwords[16] = {0};
616 	int sw_width = 21;
617 	struct vcap_admin admin = {
618 		.vtype = VCAP_TYPE_ES2, /* act_width = 21 */
619 		.cache = {
620 			.actionstream = actwords,
621 		},
622 	};
623 	struct vcap_rule_internal rule = {
624 		.admin = &admin,
625 		.data = {
626 			.actionset = VCAP_AFS_BASE_TYPE,
627 		},
628 		.vctrl = &test_vctrl,
629 	};
630 	struct vcap_client_actionfield caf = {
631 		.ctrl.list = {},
632 		.ctrl.action = VCAP_AF_POLICE_IDX,
633 		.ctrl.type = VCAP_FIELD_U32,
634 		.data.u32.value = 0x67908032,
635 	};
636 	struct vcap_field rf = {
637 		.type = VCAP_FIELD_U32,
638 		.offset = 35,
639 		.width = 6,
640 	};
641 	struct vcap_typegroup tgt[] = {
642 		{ .offset = 0, .width = 2, .value = 2, },
643 		{ .offset = 21, .width = 1, .value = 1, },
644 		{ .offset = 42, .width = 1, .value = 0, },
645 		{ .offset = 0, .width = 0, .value = 0, },
646 	};
647 
648 	vcap_encode_actionfield(&rule, &caf, &rf, tgt);
649 
650 	/* Action */
651 	KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[0]);
652 	KUNIT_EXPECT_EQ(test, (u32)((0x32 << (35 + 2 + 1 - sw_width)) & 0x1fffff), actwords[1]);
653 	KUNIT_EXPECT_EQ(test, (u32)((0x32 >> ((2 * sw_width) - 38 - 1))), actwords[2]);
654 	KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[3]);
655 	KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[4]);
656 	KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[5]);
657 	KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[6]);
658 }
659 
660 static void vcap_api_keyfield_typegroup_test(struct kunit *test)
661 {
662 	const struct vcap_typegroup *tg;
663 
664 	tg = vcap_keyfield_typegroup(&test_vctrl, VCAP_TYPE_IS2, VCAP_KFS_MAC_ETYPE);
665 	KUNIT_EXPECT_PTR_NE(test, NULL, tg);
666 	KUNIT_EXPECT_EQ(test, 0, tg[0].offset);
667 	KUNIT_EXPECT_EQ(test, 2, tg[0].width);
668 	KUNIT_EXPECT_EQ(test, 2, tg[0].value);
669 	KUNIT_EXPECT_EQ(test, 156, tg[1].offset);
670 	KUNIT_EXPECT_EQ(test, 1, tg[1].width);
671 	KUNIT_EXPECT_EQ(test, 0, tg[1].value);
672 	KUNIT_EXPECT_EQ(test, 0, tg[2].offset);
673 	KUNIT_EXPECT_EQ(test, 0, tg[2].width);
674 	KUNIT_EXPECT_EQ(test, 0, tg[2].value);
675 
676 	tg = vcap_keyfield_typegroup(&test_vctrl, VCAP_TYPE_ES2, VCAP_KFS_LL_FULL);
677 	KUNIT_EXPECT_PTR_EQ(test, NULL, tg);
678 }
679 
680 static void vcap_api_actionfield_typegroup_test(struct kunit *test)
681 {
682 	const struct vcap_typegroup *tg;
683 
684 	tg = vcap_actionfield_typegroup(&test_vctrl, VCAP_TYPE_IS0, VCAP_AFS_FULL);
685 	KUNIT_EXPECT_PTR_NE(test, NULL, tg);
686 	KUNIT_EXPECT_EQ(test, 0, tg[0].offset);
687 	KUNIT_EXPECT_EQ(test, 3, tg[0].width);
688 	KUNIT_EXPECT_EQ(test, 4, tg[0].value);
689 	KUNIT_EXPECT_EQ(test, 110, tg[1].offset);
690 	KUNIT_EXPECT_EQ(test, 2, tg[1].width);
691 	KUNIT_EXPECT_EQ(test, 0, tg[1].value);
692 	KUNIT_EXPECT_EQ(test, 220, tg[2].offset);
693 	KUNIT_EXPECT_EQ(test, 2, tg[2].width);
694 	KUNIT_EXPECT_EQ(test, 0, tg[2].value);
695 	KUNIT_EXPECT_EQ(test, 0, tg[3].offset);
696 	KUNIT_EXPECT_EQ(test, 0, tg[3].width);
697 	KUNIT_EXPECT_EQ(test, 0, tg[3].value);
698 
699 	tg = vcap_actionfield_typegroup(&test_vctrl, VCAP_TYPE_IS2, VCAP_AFS_CLASSIFICATION);
700 	KUNIT_EXPECT_PTR_EQ(test, NULL, tg);
701 }
702 
703 static void vcap_api_vcap_keyfields_test(struct kunit *test)
704 {
705 	const struct vcap_field *ft;
706 
707 	ft = vcap_keyfields(&test_vctrl, VCAP_TYPE_IS2, VCAP_KFS_MAC_ETYPE);
708 	KUNIT_EXPECT_PTR_NE(test, NULL, ft);
709 
710 	/* Keyset that is not available and within the maximum keyset enum value */
711 	ft = vcap_keyfields(&test_vctrl, VCAP_TYPE_ES2, VCAP_KFS_PURE_5TUPLE_IP4);
712 	KUNIT_EXPECT_PTR_EQ(test, NULL, ft);
713 
714 	/* Keyset that is not available and beyond the maximum keyset enum value */
715 	ft = vcap_keyfields(&test_vctrl, VCAP_TYPE_ES2, VCAP_KFS_LL_FULL);
716 	KUNIT_EXPECT_PTR_EQ(test, NULL, ft);
717 }
718 
719 static void vcap_api_vcap_actionfields_test(struct kunit *test)
720 {
721 	const struct vcap_field *ft;
722 
723 	ft = vcap_actionfields(&test_vctrl, VCAP_TYPE_IS0, VCAP_AFS_FULL);
724 	KUNIT_EXPECT_PTR_NE(test, NULL, ft);
725 
726 	ft = vcap_actionfields(&test_vctrl, VCAP_TYPE_IS2, VCAP_AFS_FULL);
727 	KUNIT_EXPECT_PTR_EQ(test, NULL, ft);
728 
729 	ft = vcap_actionfields(&test_vctrl, VCAP_TYPE_IS2, VCAP_AFS_CLASSIFICATION);
730 	KUNIT_EXPECT_PTR_EQ(test, NULL, ft);
731 }
732 
733 static void vcap_api_encode_rule_keyset_test(struct kunit *test)
734 {
735 	u32 keywords[16] = {0};
736 	u32 maskwords[16] = {0};
737 	struct vcap_admin admin = {
738 		.vtype = VCAP_TYPE_IS2,
739 		.cache = {
740 			.keystream = keywords,
741 			.maskstream = maskwords,
742 		},
743 	};
744 	struct vcap_rule_internal rule = {
745 		.admin = &admin,
746 		.data = {
747 			.keyset = VCAP_KFS_MAC_ETYPE,
748 		},
749 		.vctrl = &test_vctrl,
750 	};
751 	struct vcap_client_keyfield ckf[] = {
752 		{
753 			.ctrl.key = VCAP_KF_TYPE,
754 			.ctrl.type = VCAP_FIELD_U32,
755 			.data.u32.value = 0x00,
756 			.data.u32.mask = 0x0f,
757 		},
758 		{
759 			.ctrl.key = VCAP_KF_LOOKUP_FIRST_IS,
760 			.ctrl.type = VCAP_FIELD_BIT,
761 			.data.u1.value = 0x01,
762 			.data.u1.mask = 0x01,
763 		},
764 		{
765 			.ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_L3,
766 			.ctrl.type = VCAP_FIELD_BIT,
767 			.data.u1.value = 0x00,
768 			.data.u1.mask = 0x01,
769 		},
770 		{
771 			.ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_RNG,
772 			.ctrl.type = VCAP_FIELD_U32,
773 			.data.u32.value = 0x00,
774 			.data.u32.mask = 0x0f,
775 		},
776 		{
777 			.ctrl.key = VCAP_KF_IF_IGR_PORT_MASK,
778 			.ctrl.type = VCAP_FIELD_U72,
779 			.data.u72.value = {0x0, 0x00, 0x00, 0x00},
780 			.data.u72.mask = {0xfd, 0xff, 0xff, 0xff},
781 		},
782 		{
783 			.ctrl.key = VCAP_KF_L2_DMAC,
784 			.ctrl.type = VCAP_FIELD_U48,
785 			/* Opposite endianness */
786 			.data.u48.value = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
787 			.data.u48.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
788 		},
789 		{
790 			.ctrl.key = VCAP_KF_ETYPE_LEN_IS,
791 			.ctrl.type = VCAP_FIELD_BIT,
792 			.data.u1.value = 0x01,
793 			.data.u1.mask = 0x01,
794 		},
795 		{
796 			.ctrl.key = VCAP_KF_ETYPE,
797 			.ctrl.type = VCAP_FIELD_U32,
798 			.data.u32.value = 0xaabb,
799 			.data.u32.mask = 0xffff,
800 		},
801 	};
802 	int idx;
803 	int ret;
804 
805 	/* Empty entry list */
806 	INIT_LIST_HEAD(&rule.data.keyfields);
807 	ret = vcap_encode_rule_keyset(&rule);
808 	KUNIT_EXPECT_EQ(test, -EINVAL, ret);
809 
810 	for (idx = 0; idx < ARRAY_SIZE(ckf); idx++)
811 		list_add_tail(&ckf[idx].ctrl.list, &rule.data.keyfields);
812 	ret = vcap_encode_rule_keyset(&rule);
813 	KUNIT_EXPECT_EQ(test, 0, ret);
814 
815 	/* The key and mask values below are from an actual Sparx5 rule config */
816 	/* Key */
817 	KUNIT_EXPECT_EQ(test, (u32)0x00000042, keywords[0]);
818 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[1]);
819 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[2]);
820 	KUNIT_EXPECT_EQ(test, (u32)0x00020100, keywords[3]);
821 	KUNIT_EXPECT_EQ(test, (u32)0x60504030, keywords[4]);
822 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[5]);
823 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[6]);
824 	KUNIT_EXPECT_EQ(test, (u32)0x0002aaee, keywords[7]);
825 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[8]);
826 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[9]);
827 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[10]);
828 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[11]);
829 
830 	/* Mask: they will be inverted when applied to the register */
831 	KUNIT_EXPECT_EQ(test, (u32)~0x00b07f80, maskwords[0]);
832 	KUNIT_EXPECT_EQ(test, (u32)~0xfff00000, maskwords[1]);
833 	KUNIT_EXPECT_EQ(test, (u32)~0xfffffffc, maskwords[2]);
834 	KUNIT_EXPECT_EQ(test, (u32)~0xfff000ff, maskwords[3]);
835 	KUNIT_EXPECT_EQ(test, (u32)~0x00000000, maskwords[4]);
836 	KUNIT_EXPECT_EQ(test, (u32)~0xfffffff0, maskwords[5]);
837 	KUNIT_EXPECT_EQ(test, (u32)~0xfffffffe, maskwords[6]);
838 	KUNIT_EXPECT_EQ(test, (u32)~0xfffc0001, maskwords[7]);
839 	KUNIT_EXPECT_EQ(test, (u32)~0xffffffff, maskwords[8]);
840 	KUNIT_EXPECT_EQ(test, (u32)~0xffffffff, maskwords[9]);
841 	KUNIT_EXPECT_EQ(test, (u32)~0xffffffff, maskwords[10]);
842 	KUNIT_EXPECT_EQ(test, (u32)~0xffffffff, maskwords[11]);
843 }
844 
845 static void vcap_api_encode_rule_actionset_test(struct kunit *test)
846 {
847 	u32 actwords[16] = {0};
848 	struct vcap_admin admin = {
849 		.vtype = VCAP_TYPE_IS2,
850 		.cache = {
851 			.actionstream = actwords,
852 		},
853 	};
854 	struct vcap_rule_internal rule = {
855 		.admin = &admin,
856 		.data = {
857 			.actionset = VCAP_AFS_BASE_TYPE,
858 		},
859 		.vctrl = &test_vctrl,
860 	};
861 	struct vcap_client_actionfield caf[] = {
862 		{
863 			.ctrl.action = VCAP_AF_MATCH_ID,
864 			.ctrl.type = VCAP_FIELD_U32,
865 			.data.u32.value = 0x01,
866 		},
867 		{
868 			.ctrl.action = VCAP_AF_MATCH_ID_MASK,
869 			.ctrl.type = VCAP_FIELD_U32,
870 			.data.u32.value = 0x01,
871 		},
872 		{
873 			.ctrl.action = VCAP_AF_CNT_ID,
874 			.ctrl.type = VCAP_FIELD_U32,
875 			.data.u32.value = 0x64,
876 		},
877 	};
878 	int idx;
879 	int ret;
880 
881 	/* Empty entry list */
882 	INIT_LIST_HEAD(&rule.data.actionfields);
883 	ret = vcap_encode_rule_actionset(&rule);
884 	/* We allow rules with no actions */
885 	KUNIT_EXPECT_EQ(test, 0, ret);
886 
887 	for (idx = 0; idx < ARRAY_SIZE(caf); idx++)
888 		list_add_tail(&caf[idx].ctrl.list, &rule.data.actionfields);
889 	ret = vcap_encode_rule_actionset(&rule);
890 	KUNIT_EXPECT_EQ(test, 0, ret);
891 
892 	/* The action values below are from an actual Sparx5 rule config */
893 	KUNIT_EXPECT_EQ(test, (u32)0x00000002, actwords[0]);
894 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[1]);
895 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[2]);
896 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[3]);
897 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[4]);
898 	KUNIT_EXPECT_EQ(test, (u32)0x00100000, actwords[5]);
899 	KUNIT_EXPECT_EQ(test, (u32)0x06400010, actwords[6]);
900 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[7]);
901 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[8]);
902 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[9]);
903 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[10]);
904 	KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[11]);
905 }
906 
907 static struct kunit_case vcap_api_encoding_test_cases[] = {
908 	KUNIT_CASE(vcap_api_set_bit_1_test),
909 	KUNIT_CASE(vcap_api_set_bit_0_test),
910 	KUNIT_CASE(vcap_api_iterator_init_test),
911 	KUNIT_CASE(vcap_api_iterator_next_test),
912 	KUNIT_CASE(vcap_api_encode_typegroups_test),
913 	KUNIT_CASE(vcap_api_encode_bit_test),
914 	KUNIT_CASE(vcap_api_encode_field_test),
915 	KUNIT_CASE(vcap_api_encode_short_field_test),
916 	KUNIT_CASE(vcap_api_encode_keyfield_test),
917 	KUNIT_CASE(vcap_api_encode_max_keyfield_test),
918 	KUNIT_CASE(vcap_api_encode_actionfield_test),
919 	KUNIT_CASE(vcap_api_keyfield_typegroup_test),
920 	KUNIT_CASE(vcap_api_actionfield_typegroup_test),
921 	KUNIT_CASE(vcap_api_vcap_keyfields_test),
922 	KUNIT_CASE(vcap_api_vcap_actionfields_test),
923 	KUNIT_CASE(vcap_api_encode_rule_keyset_test),
924 	KUNIT_CASE(vcap_api_encode_rule_actionset_test),
925 	{}
926 };
927 
928 static struct kunit_suite vcap_api_encoding_test_suite = {
929 	.name = "VCAP_API_Encoding_Testsuite",
930 	.test_cases = vcap_api_encoding_test_cases,
931 };
932 
933 kunit_test_suite(vcap_api_encoding_test_suite);
934