1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
217a937baSMairtin o Loingsigh * Copyright(c) 2017-2020 Intel Corporation
3a9de470cSBruce Richardson */
4a9de470cSBruce Richardson
5a9de470cSBruce Richardson #include "test.h"
6a9de470cSBruce Richardson
7a9de470cSBruce Richardson #include <rte_hexdump.h>
8a9de470cSBruce Richardson #include <rte_malloc.h>
9a9de470cSBruce Richardson #include <rte_memcpy.h>
10a9de470cSBruce Richardson #include <rte_net_crc.h>
11a9de470cSBruce Richardson
12a9de470cSBruce Richardson #define CRC_VEC_LEN 32
13a9de470cSBruce Richardson #define CRC32_VEC_LEN1 1512
14a9de470cSBruce Richardson #define CRC32_VEC_LEN2 348
15a9de470cSBruce Richardson #define CRC16_VEC_LEN1 12
16a9de470cSBruce Richardson #define CRC16_VEC_LEN2 2
17a9de470cSBruce Richardson
18a9de470cSBruce Richardson /* CRC test vector */
19a9de470cSBruce Richardson static const uint8_t crc_vec[CRC_VEC_LEN] = {
20a9de470cSBruce Richardson '0', '1', '2', '3', '4', '5', '6', '7',
21a9de470cSBruce Richardson '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
22a9de470cSBruce Richardson 'g', 'h', 'i', 'j', 'A', 'B', 'C', 'D',
23a9de470cSBruce Richardson 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
24a9de470cSBruce Richardson };
25a9de470cSBruce Richardson
26a9de470cSBruce Richardson /* 32-bit CRC test vector */
27a9de470cSBruce Richardson static const uint8_t crc32_vec1[12] = {
28a9de470cSBruce Richardson 0xBE, 0xD7, 0x23, 0x47, 0x6B, 0x8F,
29a9de470cSBruce Richardson 0xB3, 0x14, 0x5E, 0xFB, 0x35, 0x59,
30a9de470cSBruce Richardson };
31a9de470cSBruce Richardson
32a9de470cSBruce Richardson /* 16-bit CRC test vector 1 */
33a9de470cSBruce Richardson static const uint8_t crc16_vec1[CRC16_VEC_LEN1] = {
34a9de470cSBruce Richardson 0x0D, 0x01, 0x01, 0x23, 0x45, 0x67,
35a9de470cSBruce Richardson 0x89, 0x01, 0x23, 0x45, 0x00, 0x01,
36a9de470cSBruce Richardson };
37a9de470cSBruce Richardson
38a9de470cSBruce Richardson /* 16-bit CRC test vector 2 */
39a9de470cSBruce Richardson static const uint8_t crc16_vec2[CRC16_VEC_LEN2] = {
40a9de470cSBruce Richardson 0x03, 0x3f,
41a9de470cSBruce Richardson };
42a9de470cSBruce Richardson /** CRC results */
43a9de470cSBruce Richardson static const uint32_t crc32_vec_res = 0xb491aab4;
44a9de470cSBruce Richardson static const uint32_t crc32_vec1_res = 0xac54d294;
45a9de470cSBruce Richardson static const uint32_t crc32_vec2_res = 0xefaae02f;
46a9de470cSBruce Richardson static const uint32_t crc16_vec_res = 0x6bec;
47a9de470cSBruce Richardson static const uint16_t crc16_vec1_res = 0x8cdd;
48a9de470cSBruce Richardson static const uint16_t crc16_vec2_res = 0xec5b;
49a9de470cSBruce Richardson
50a9de470cSBruce Richardson static int
crc_calc(const uint8_t * vec,uint32_t vec_len,enum rte_net_crc_type type)51a9de470cSBruce Richardson crc_calc(const uint8_t *vec,
52a9de470cSBruce Richardson uint32_t vec_len,
53a9de470cSBruce Richardson enum rte_net_crc_type type)
54a9de470cSBruce Richardson {
55a9de470cSBruce Richardson /* compute CRC */
56a9de470cSBruce Richardson uint32_t ret = rte_net_crc_calc(vec, vec_len, type);
57a9de470cSBruce Richardson
58a9de470cSBruce Richardson /* dump data on console */
59a9de470cSBruce Richardson debug_hexdump(stdout, NULL, vec, vec_len);
60a9de470cSBruce Richardson
61a9de470cSBruce Richardson return ret;
62a9de470cSBruce Richardson }
63a9de470cSBruce Richardson
64a9de470cSBruce Richardson static int
test_crc_calc(void)65a9de470cSBruce Richardson test_crc_calc(void)
66a9de470cSBruce Richardson {
67a9de470cSBruce Richardson uint32_t i;
68a9de470cSBruce Richardson enum rte_net_crc_type type;
69a9de470cSBruce Richardson uint8_t *test_data;
70a9de470cSBruce Richardson uint32_t result;
71a9de470cSBruce Richardson int error;
72a9de470cSBruce Richardson
73a9de470cSBruce Richardson /* 32-bit ethernet CRC: Test 1 */
74a9de470cSBruce Richardson type = RTE_NET_CRC32_ETH;
75a9de470cSBruce Richardson
76a9de470cSBruce Richardson result = crc_calc(crc_vec, CRC_VEC_LEN, type);
77a9de470cSBruce Richardson if (result != crc32_vec_res)
78a9de470cSBruce Richardson return -1;
79a9de470cSBruce Richardson
80a9de470cSBruce Richardson /* 32-bit ethernet CRC: Test 2 */
81a9de470cSBruce Richardson test_data = rte_zmalloc(NULL, CRC32_VEC_LEN1, 0);
8252aab954SHongbo Zheng if (test_data == NULL)
8352aab954SHongbo Zheng return -7;
84a9de470cSBruce Richardson
85a9de470cSBruce Richardson for (i = 0; i < CRC32_VEC_LEN1; i += 12)
86a9de470cSBruce Richardson rte_memcpy(&test_data[i], crc32_vec1, 12);
87a9de470cSBruce Richardson
88a9de470cSBruce Richardson result = crc_calc(test_data, CRC32_VEC_LEN1, type);
89a9de470cSBruce Richardson if (result != crc32_vec1_res) {
90a9de470cSBruce Richardson error = -2;
91a9de470cSBruce Richardson goto fail;
92a9de470cSBruce Richardson }
93a9de470cSBruce Richardson
94a9de470cSBruce Richardson /* 32-bit ethernet CRC: Test 3 */
95a9de470cSBruce Richardson for (i = 0; i < CRC32_VEC_LEN2; i += 12)
96a9de470cSBruce Richardson rte_memcpy(&test_data[i], crc32_vec1, 12);
97a9de470cSBruce Richardson
98a9de470cSBruce Richardson result = crc_calc(test_data, CRC32_VEC_LEN2, type);
99a9de470cSBruce Richardson if (result != crc32_vec2_res) {
100a9de470cSBruce Richardson error = -3;
101a9de470cSBruce Richardson goto fail;
102a9de470cSBruce Richardson }
103a9de470cSBruce Richardson
104a9de470cSBruce Richardson /* 16-bit CCITT CRC: Test 4 */
105a9de470cSBruce Richardson type = RTE_NET_CRC16_CCITT;
106a9de470cSBruce Richardson result = crc_calc(crc_vec, CRC_VEC_LEN, type);
107a9de470cSBruce Richardson if (result != crc16_vec_res) {
108a9de470cSBruce Richardson error = -4;
109a9de470cSBruce Richardson goto fail;
110a9de470cSBruce Richardson }
111a9de470cSBruce Richardson /* 16-bit CCITT CRC: Test 5 */
112a9de470cSBruce Richardson result = crc_calc(crc16_vec1, CRC16_VEC_LEN1, type);
113a9de470cSBruce Richardson if (result != crc16_vec1_res) {
114a9de470cSBruce Richardson error = -5;
115a9de470cSBruce Richardson goto fail;
116a9de470cSBruce Richardson }
117a9de470cSBruce Richardson /* 16-bit CCITT CRC: Test 6 */
118a9de470cSBruce Richardson result = crc_calc(crc16_vec2, CRC16_VEC_LEN2, type);
119a9de470cSBruce Richardson if (result != crc16_vec2_res) {
120a9de470cSBruce Richardson error = -6;
121a9de470cSBruce Richardson goto fail;
122a9de470cSBruce Richardson }
123a9de470cSBruce Richardson
124a9de470cSBruce Richardson rte_free(test_data);
125a9de470cSBruce Richardson return 0;
126a9de470cSBruce Richardson
127a9de470cSBruce Richardson fail:
128a9de470cSBruce Richardson rte_free(test_data);
129a9de470cSBruce Richardson return error;
130a9de470cSBruce Richardson }
131a9de470cSBruce Richardson
132a9de470cSBruce Richardson static int
test_crc(void)133a9de470cSBruce Richardson test_crc(void)
134a9de470cSBruce Richardson {
135a9de470cSBruce Richardson int ret;
136a9de470cSBruce Richardson /* set CRC scalar mode */
137a9de470cSBruce Richardson rte_net_crc_set_alg(RTE_NET_CRC_SCALAR);
138a9de470cSBruce Richardson
139a9de470cSBruce Richardson ret = test_crc_calc();
140a9de470cSBruce Richardson if (ret < 0) {
141a9de470cSBruce Richardson printf("test_crc (scalar): failed (%d)\n", ret);
142a9de470cSBruce Richardson return ret;
143a9de470cSBruce Richardson }
144a9de470cSBruce Richardson /* set CRC sse4.2 mode */
145a9de470cSBruce Richardson rte_net_crc_set_alg(RTE_NET_CRC_SSE42);
146a9de470cSBruce Richardson
147a9de470cSBruce Richardson ret = test_crc_calc();
148a9de470cSBruce Richardson if (ret < 0) {
149a9de470cSBruce Richardson printf("test_crc (x86_64_SSE4.2): failed (%d)\n", ret);
150a9de470cSBruce Richardson return ret;
151a9de470cSBruce Richardson }
152a9de470cSBruce Richardson
15317a937baSMairtin o Loingsigh /* set CRC avx512 mode */
15417a937baSMairtin o Loingsigh rte_net_crc_set_alg(RTE_NET_CRC_AVX512);
15517a937baSMairtin o Loingsigh
15617a937baSMairtin o Loingsigh ret = test_crc_calc();
15717a937baSMairtin o Loingsigh if (ret < 0) {
15817a937baSMairtin o Loingsigh printf("test crc (x86_64 AVX512): failed (%d)\n", ret);
15917a937baSMairtin o Loingsigh return ret;
16017a937baSMairtin o Loingsigh }
16117a937baSMairtin o Loingsigh
162a9de470cSBruce Richardson /* set CRC neon mode */
163a9de470cSBruce Richardson rte_net_crc_set_alg(RTE_NET_CRC_NEON);
164a9de470cSBruce Richardson
165a9de470cSBruce Richardson ret = test_crc_calc();
166a9de470cSBruce Richardson if (ret < 0) {
167a9de470cSBruce Richardson printf("test crc (arm64 neon pmull): failed (%d)\n", ret);
168a9de470cSBruce Richardson return ret;
169a9de470cSBruce Richardson }
170a9de470cSBruce Richardson
171a9de470cSBruce Richardson return 0;
172a9de470cSBruce Richardson }
173a9de470cSBruce Richardson
174*e0a8442cSBruce Richardson REGISTER_FAST_TEST(crc_autotest, true, true, test_crc);
175