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