14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606 * Copyright(c) 2017-2020 Intel Corporation
34418919fSjohnjiang */
44418919fSjohnjiang
54418919fSjohnjiang #include "test.h"
64418919fSjohnjiang
74418919fSjohnjiang #include <rte_hexdump.h>
84418919fSjohnjiang #include <rte_malloc.h>
94418919fSjohnjiang #include <rte_memcpy.h>
104418919fSjohnjiang #include <rte_net_crc.h>
114418919fSjohnjiang
124418919fSjohnjiang #define CRC_VEC_LEN 32
134418919fSjohnjiang #define CRC32_VEC_LEN1 1512
144418919fSjohnjiang #define CRC32_VEC_LEN2 348
154418919fSjohnjiang #define CRC16_VEC_LEN1 12
164418919fSjohnjiang #define CRC16_VEC_LEN2 2
174418919fSjohnjiang #define LINE_LEN 75
184418919fSjohnjiang
194418919fSjohnjiang /* CRC test vector */
204418919fSjohnjiang static const uint8_t crc_vec[CRC_VEC_LEN] = {
214418919fSjohnjiang '0', '1', '2', '3', '4', '5', '6', '7',
224418919fSjohnjiang '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
234418919fSjohnjiang 'g', 'h', 'i', 'j', 'A', 'B', 'C', 'D',
244418919fSjohnjiang 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
254418919fSjohnjiang };
264418919fSjohnjiang
274418919fSjohnjiang /* 32-bit CRC test vector */
284418919fSjohnjiang static const uint8_t crc32_vec1[12] = {
294418919fSjohnjiang 0xBE, 0xD7, 0x23, 0x47, 0x6B, 0x8F,
304418919fSjohnjiang 0xB3, 0x14, 0x5E, 0xFB, 0x35, 0x59,
314418919fSjohnjiang };
324418919fSjohnjiang
334418919fSjohnjiang /* 16-bit CRC test vector 1 */
344418919fSjohnjiang static const uint8_t crc16_vec1[CRC16_VEC_LEN1] = {
354418919fSjohnjiang 0x0D, 0x01, 0x01, 0x23, 0x45, 0x67,
364418919fSjohnjiang 0x89, 0x01, 0x23, 0x45, 0x00, 0x01,
374418919fSjohnjiang };
384418919fSjohnjiang
394418919fSjohnjiang /* 16-bit CRC test vector 2 */
404418919fSjohnjiang static const uint8_t crc16_vec2[CRC16_VEC_LEN2] = {
414418919fSjohnjiang 0x03, 0x3f,
424418919fSjohnjiang };
434418919fSjohnjiang /** CRC results */
444418919fSjohnjiang static const uint32_t crc32_vec_res = 0xb491aab4;
454418919fSjohnjiang static const uint32_t crc32_vec1_res = 0xac54d294;
464418919fSjohnjiang static const uint32_t crc32_vec2_res = 0xefaae02f;
474418919fSjohnjiang static const uint32_t crc16_vec_res = 0x6bec;
484418919fSjohnjiang static const uint16_t crc16_vec1_res = 0x8cdd;
494418919fSjohnjiang static const uint16_t crc16_vec2_res = 0xec5b;
504418919fSjohnjiang
514418919fSjohnjiang static int
crc_calc(const uint8_t * vec,uint32_t vec_len,enum rte_net_crc_type type)524418919fSjohnjiang crc_calc(const uint8_t *vec,
534418919fSjohnjiang uint32_t vec_len,
544418919fSjohnjiang enum rte_net_crc_type type)
554418919fSjohnjiang {
564418919fSjohnjiang /* compute CRC */
574418919fSjohnjiang uint32_t ret = rte_net_crc_calc(vec, vec_len, type);
584418919fSjohnjiang
594418919fSjohnjiang /* dump data on console */
604418919fSjohnjiang debug_hexdump(stdout, NULL, vec, vec_len);
614418919fSjohnjiang
624418919fSjohnjiang return ret;
634418919fSjohnjiang }
644418919fSjohnjiang
654418919fSjohnjiang static int
test_crc_calc(void)664418919fSjohnjiang test_crc_calc(void)
674418919fSjohnjiang {
684418919fSjohnjiang uint32_t i;
694418919fSjohnjiang enum rte_net_crc_type type;
704418919fSjohnjiang uint8_t *test_data;
714418919fSjohnjiang uint32_t result;
724418919fSjohnjiang int error;
734418919fSjohnjiang
744418919fSjohnjiang /* 32-bit ethernet CRC: Test 1 */
754418919fSjohnjiang type = RTE_NET_CRC32_ETH;
764418919fSjohnjiang
774418919fSjohnjiang result = crc_calc(crc_vec, CRC_VEC_LEN, type);
784418919fSjohnjiang if (result != crc32_vec_res)
794418919fSjohnjiang return -1;
804418919fSjohnjiang
814418919fSjohnjiang /* 32-bit ethernet CRC: Test 2 */
824418919fSjohnjiang test_data = rte_zmalloc(NULL, CRC32_VEC_LEN1, 0);
834418919fSjohnjiang
844418919fSjohnjiang for (i = 0; i < CRC32_VEC_LEN1; i += 12)
854418919fSjohnjiang rte_memcpy(&test_data[i], crc32_vec1, 12);
864418919fSjohnjiang
874418919fSjohnjiang result = crc_calc(test_data, CRC32_VEC_LEN1, type);
884418919fSjohnjiang if (result != crc32_vec1_res) {
894418919fSjohnjiang error = -2;
904418919fSjohnjiang goto fail;
914418919fSjohnjiang }
924418919fSjohnjiang
934418919fSjohnjiang /* 32-bit ethernet CRC: Test 3 */
944418919fSjohnjiang for (i = 0; i < CRC32_VEC_LEN2; i += 12)
954418919fSjohnjiang rte_memcpy(&test_data[i], crc32_vec1, 12);
964418919fSjohnjiang
974418919fSjohnjiang result = crc_calc(test_data, CRC32_VEC_LEN2, type);
984418919fSjohnjiang if (result != crc32_vec2_res) {
994418919fSjohnjiang error = -3;
1004418919fSjohnjiang goto fail;
1014418919fSjohnjiang }
1024418919fSjohnjiang
1034418919fSjohnjiang /* 16-bit CCITT CRC: Test 4 */
1044418919fSjohnjiang type = RTE_NET_CRC16_CCITT;
1054418919fSjohnjiang result = crc_calc(crc_vec, CRC_VEC_LEN, type);
1064418919fSjohnjiang if (result != crc16_vec_res) {
1074418919fSjohnjiang error = -4;
1084418919fSjohnjiang goto fail;
1094418919fSjohnjiang }
1104418919fSjohnjiang /* 16-bit CCITT CRC: Test 5 */
1114418919fSjohnjiang result = crc_calc(crc16_vec1, CRC16_VEC_LEN1, type);
1124418919fSjohnjiang if (result != crc16_vec1_res) {
1134418919fSjohnjiang error = -5;
1144418919fSjohnjiang goto fail;
1154418919fSjohnjiang }
1164418919fSjohnjiang /* 16-bit CCITT CRC: Test 6 */
1174418919fSjohnjiang result = crc_calc(crc16_vec2, CRC16_VEC_LEN2, type);
1184418919fSjohnjiang if (result != crc16_vec2_res) {
1194418919fSjohnjiang error = -6;
1204418919fSjohnjiang goto fail;
1214418919fSjohnjiang }
1224418919fSjohnjiang
1234418919fSjohnjiang rte_free(test_data);
1244418919fSjohnjiang return 0;
1254418919fSjohnjiang
1264418919fSjohnjiang fail:
1274418919fSjohnjiang rte_free(test_data);
1284418919fSjohnjiang return error;
1294418919fSjohnjiang }
1304418919fSjohnjiang
1314418919fSjohnjiang static int
test_crc(void)1324418919fSjohnjiang test_crc(void)
1334418919fSjohnjiang {
1344418919fSjohnjiang int ret;
1354418919fSjohnjiang /* set CRC scalar mode */
1364418919fSjohnjiang rte_net_crc_set_alg(RTE_NET_CRC_SCALAR);
1374418919fSjohnjiang
1384418919fSjohnjiang ret = test_crc_calc();
1394418919fSjohnjiang if (ret < 0) {
1404418919fSjohnjiang printf("test_crc (scalar): failed (%d)\n", ret);
1414418919fSjohnjiang return ret;
1424418919fSjohnjiang }
1434418919fSjohnjiang /* set CRC sse4.2 mode */
1444418919fSjohnjiang rte_net_crc_set_alg(RTE_NET_CRC_SSE42);
1454418919fSjohnjiang
1464418919fSjohnjiang ret = test_crc_calc();
1474418919fSjohnjiang if (ret < 0) {
1484418919fSjohnjiang printf("test_crc (x86_64_SSE4.2): failed (%d)\n", ret);
1494418919fSjohnjiang return ret;
1504418919fSjohnjiang }
1514418919fSjohnjiang
152*2d9fd380Sjfb8856606 /* set CRC avx512 mode */
153*2d9fd380Sjfb8856606 rte_net_crc_set_alg(RTE_NET_CRC_AVX512);
154*2d9fd380Sjfb8856606
155*2d9fd380Sjfb8856606 ret = test_crc_calc();
156*2d9fd380Sjfb8856606 if (ret < 0) {
157*2d9fd380Sjfb8856606 printf("test crc (x86_64 AVX512): failed (%d)\n", ret);
158*2d9fd380Sjfb8856606 return ret;
159*2d9fd380Sjfb8856606 }
160*2d9fd380Sjfb8856606
1614418919fSjohnjiang /* set CRC neon mode */
1624418919fSjohnjiang rte_net_crc_set_alg(RTE_NET_CRC_NEON);
1634418919fSjohnjiang
1644418919fSjohnjiang ret = test_crc_calc();
1654418919fSjohnjiang if (ret < 0) {
1664418919fSjohnjiang printf("test crc (arm64 neon pmull): failed (%d)\n", ret);
1674418919fSjohnjiang return ret;
1684418919fSjohnjiang }
1694418919fSjohnjiang
1704418919fSjohnjiang return 0;
1714418919fSjohnjiang }
1724418919fSjohnjiang
1734418919fSjohnjiang REGISTER_TEST_COMMAND(crc_autotest, test_crc);
174