xref: /dpdk/app/test-bbdev/test_bbdev_vector.c (revision 25d11a86c56d50947af33d0b79ede622809bd8b9)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4 
5 #ifdef RTE_EXEC_ENV_BSDAPP
6 	#define _WITH_GETLINE
7 #endif
8 #include <stdio.h>
9 #include <stdbool.h>
10 #include <rte_malloc.h>
11 
12 #include "test_bbdev_vector.h"
13 
14 #define VALUE_DELIMITER ","
15 #define ENTRY_DELIMITER "="
16 
17 const char *op_data_prefixes[] = {
18 	"input",
19 	"soft_output",
20 	"hard_output",
21 };
22 
23 /* trim leading and trailing spaces */
24 static void
25 trim_space(char *str)
26 {
27 	char *start, *end;
28 
29 	for (start = str; *start; start++) {
30 		if (!isspace((unsigned char) start[0]))
31 			break;
32 	}
33 
34 	for (end = start + strlen(start); end > start + 1; end--) {
35 		if (!isspace((unsigned char) end[-1]))
36 			break;
37 	}
38 
39 	*end = 0;
40 
41 	/* Shift from "start" to the beginning of the string */
42 	if (start > str)
43 		memmove(str, start, (end - start) + 1);
44 }
45 
46 static bool
47 starts_with(const char *str, const char *pre)
48 {
49 	return strncmp(pre, str, strlen(pre)) == 0;
50 }
51 
52 /* tokenization test values separated by a comma */
53 static int
54 parse_values(char *tokens, uint32_t **data, uint32_t *data_length)
55 {
56 	uint32_t n_tokens = 0;
57 	uint32_t data_size = 32;
58 
59 	uint32_t *values, *values_resized;
60 	char *tok, *error = NULL;
61 
62 	tok = strtok(tokens, VALUE_DELIMITER);
63 	if (tok == NULL)
64 		return -1;
65 
66 	values = (uint32_t *)
67 			rte_zmalloc(NULL, sizeof(uint32_t) * data_size, 0);
68 	if (values == NULL)
69 		return -1;
70 
71 	while (tok != NULL) {
72 		values_resized = NULL;
73 
74 		if (n_tokens >= data_size) {
75 			data_size *= 2;
76 
77 			values_resized = (uint32_t *) rte_realloc(values,
78 				sizeof(uint32_t) * data_size, 0);
79 			if (values_resized == NULL) {
80 				rte_free(values);
81 				return -1;
82 			}
83 			values = values_resized;
84 		}
85 
86 		values[n_tokens] = (uint32_t) strtoul(tok, &error, 0);
87 		if ((error == NULL) || (*error != '\0')) {
88 			printf("Failed with convert '%s'\n", tok);
89 			rte_free(values);
90 			return -1;
91 		}
92 
93 		*data_length = *data_length + (strlen(tok) - strlen("0x"))/2;
94 
95 		tok = strtok(NULL, VALUE_DELIMITER);
96 		if (tok == NULL)
97 			break;
98 
99 		n_tokens++;
100 	}
101 
102 	values_resized = (uint32_t *) rte_realloc(values,
103 		sizeof(uint32_t) * (n_tokens + 1), 0);
104 
105 	if (values_resized == NULL) {
106 		rte_free(values);
107 		return -1;
108 	}
109 
110 	*data = values_resized;
111 
112 	return 0;
113 }
114 
115 /* convert turbo decoder flag from string to unsigned long int*/
116 static int
117 op_decoder_flag_strtoul(char *token, uint32_t *op_flag_value)
118 {
119 	if (!strcmp(token, "RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE"))
120 		*op_flag_value = RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE;
121 	else if (!strcmp(token, "RTE_BBDEV_TURBO_CRC_TYPE_24B"))
122 		*op_flag_value = RTE_BBDEV_TURBO_CRC_TYPE_24B;
123 	else if (!strcmp(token, "RTE_BBDEV_TURBO_EQUALIZER"))
124 		*op_flag_value = RTE_BBDEV_TURBO_EQUALIZER;
125 	else if (!strcmp(token, "RTE_BBDEV_TURBO_SOFT_OUT_SATURATE"))
126 		*op_flag_value = RTE_BBDEV_TURBO_SOFT_OUT_SATURATE;
127 	else if (!strcmp(token, "RTE_BBDEV_TURBO_HALF_ITERATION_EVEN"))
128 		*op_flag_value = RTE_BBDEV_TURBO_HALF_ITERATION_EVEN;
129 	else if (!strcmp(token, "RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH"))
130 		*op_flag_value = RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH;
131 	else if (!strcmp(token, "RTE_BBDEV_TURBO_SOFT_OUTPUT"))
132 		*op_flag_value = RTE_BBDEV_TURBO_SOFT_OUTPUT;
133 	else if (!strcmp(token, "RTE_BBDEV_TURBO_EARLY_TERMINATION"))
134 		*op_flag_value = RTE_BBDEV_TURBO_EARLY_TERMINATION;
135 	else if (!strcmp(token, "RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN"))
136 		*op_flag_value = RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN;
137 	else if (!strcmp(token, "RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN"))
138 		*op_flag_value = RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN;
139 	else if (!strcmp(token, "RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT"))
140 		*op_flag_value = RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT;
141 	else if (!strcmp(token, "RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT"))
142 		*op_flag_value = RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT;
143 	else if (!strcmp(token, "RTE_BBDEV_TURBO_MAP_DEC"))
144 		*op_flag_value = RTE_BBDEV_TURBO_MAP_DEC;
145 	else if (!strcmp(token, "RTE_BBDEV_TURBO_DEC_SCATTER_GATHER"))
146 		*op_flag_value = RTE_BBDEV_TURBO_DEC_SCATTER_GATHER;
147 	else if (!strcmp(token, "RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP"))
148 		*op_flag_value = RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP;
149 	else {
150 		printf("The given value is not a turbo decoder flag\n");
151 		return -1;
152 	}
153 
154 	return 0;
155 }
156 
157 /* convert turbo encoder flag from string to unsigned long int*/
158 static int
159 op_encoder_flag_strtoul(char *token, uint32_t *op_flag_value)
160 {
161 	if (!strcmp(token, "RTE_BBDEV_TURBO_RV_INDEX_BYPASS"))
162 		*op_flag_value = RTE_BBDEV_TURBO_RV_INDEX_BYPASS;
163 	else if (!strcmp(token, "RTE_BBDEV_TURBO_RATE_MATCH"))
164 		*op_flag_value = RTE_BBDEV_TURBO_RATE_MATCH;
165 	else if (!strcmp(token, "RTE_BBDEV_TURBO_CRC_24B_ATTACH"))
166 		*op_flag_value = RTE_BBDEV_TURBO_CRC_24B_ATTACH;
167 	else if (!strcmp(token, "RTE_BBDEV_TURBO_CRC_24A_ATTACH"))
168 		*op_flag_value = RTE_BBDEV_TURBO_CRC_24A_ATTACH;
169 	else if (!strcmp(token, "RTE_BBDEV_TURBO_ENC_SCATTER_GATHER"))
170 		*op_flag_value = RTE_BBDEV_TURBO_ENC_SCATTER_GATHER;
171 	else {
172 		printf("The given value is not a turbo encoder flag\n");
173 		return -1;
174 	}
175 
176 	return 0;
177 }
178 
179 /* tokenization turbo decoder/encoder flags values separated by a comma */
180 static int
181 parse_turbo_flags(char *tokens, uint32_t *op_flags,
182 		enum rte_bbdev_op_type op_type)
183 {
184 	char *tok = NULL;
185 	uint32_t op_flag_value = 0;
186 
187 	tok = strtok(tokens, VALUE_DELIMITER);
188 	if (tok == NULL)
189 		return -1;
190 
191 	while (tok != NULL) {
192 		trim_space(tok);
193 		if (op_type == RTE_BBDEV_OP_TURBO_DEC) {
194 			if (op_decoder_flag_strtoul(tok, &op_flag_value) == -1)
195 				return -1;
196 		} else if (op_type == RTE_BBDEV_OP_TURBO_ENC) {
197 			if (op_encoder_flag_strtoul(tok, &op_flag_value) == -1)
198 				return -1;
199 		} else {
200 			return -1;
201 		}
202 
203 		*op_flags = *op_flags | op_flag_value;
204 
205 		tok = strtok(NULL, VALUE_DELIMITER);
206 		if (tok == NULL)
207 			break;
208 	}
209 
210 	return 0;
211 }
212 
213 /* convert turbo encoder/decoder op_type from string to enum*/
214 static int
215 op_turbo_type_strtol(char *token, enum rte_bbdev_op_type *op_type)
216 {
217 	trim_space(token);
218 	if (!strcmp(token, "RTE_BBDEV_OP_TURBO_DEC"))
219 		*op_type = RTE_BBDEV_OP_TURBO_DEC;
220 	else if (!strcmp(token, "RTE_BBDEV_OP_TURBO_ENC"))
221 		*op_type = RTE_BBDEV_OP_TURBO_ENC;
222 	else if (!strcmp(token, "RTE_BBDEV_OP_NONE"))
223 		*op_type = RTE_BBDEV_OP_NONE;
224 	else {
225 		printf("Not valid turbo op_type: '%s'\n", token);
226 		return -1;
227 	}
228 
229 	return 0;
230 }
231 
232 /* tokenization expected status values separated by a comma */
233 static int
234 parse_expected_status(char *tokens, int *status, enum rte_bbdev_op_type op_type)
235 {
236 	char *tok = NULL;
237 	bool status_ok = false;
238 
239 	tok = strtok(tokens, VALUE_DELIMITER);
240 	if (tok == NULL)
241 		return -1;
242 
243 	while (tok != NULL) {
244 		trim_space(tok);
245 		if (!strcmp(tok, "OK"))
246 			status_ok = true;
247 		else if (!strcmp(tok, "DMA"))
248 			*status = *status | (1 << RTE_BBDEV_DRV_ERROR);
249 		else if (!strcmp(tok, "FCW"))
250 			*status = *status | (1 << RTE_BBDEV_DATA_ERROR);
251 		else if (!strcmp(tok, "CRC")) {
252 			if (op_type == RTE_BBDEV_OP_TURBO_DEC)
253 				*status = *status | (1 << RTE_BBDEV_CRC_ERROR);
254 			else {
255 				printf(
256 						"CRC is only a valid value for turbo decoder\n");
257 				return -1;
258 			}
259 		} else {
260 			printf("Not valid status: '%s'\n", tok);
261 			return -1;
262 		}
263 
264 		tok = strtok(NULL, VALUE_DELIMITER);
265 		if (tok == NULL)
266 			break;
267 	}
268 
269 	if (status_ok && *status != 0) {
270 		printf(
271 				"Not valid status values. Cannot be OK and ERROR at the same time.\n");
272 		return -1;
273 	}
274 
275 	return 0;
276 }
277 
278 /* parse ops data entry (there can be more than 1 input entry, each will be
279  * contained in a separate op_data_buf struct)
280  */
281 static int
282 parse_data_entry(const char *key_token, char *token,
283 		struct test_bbdev_vector *vector, enum op_data_type type,
284 		const char *prefix)
285 {
286 	int ret;
287 	uint32_t data_length = 0;
288 	uint32_t *data = NULL;
289 	unsigned int id;
290 	struct op_data_buf *op_data;
291 	unsigned int *nb_ops;
292 
293 	if (type >= DATA_NUM_TYPES) {
294 		printf("Unknown op type: %d!\n", type);
295 		return -1;
296 	}
297 
298 	op_data = vector->entries[type].segments;
299 	nb_ops = &vector->entries[type].nb_segments;
300 
301 	if (*nb_ops >= RTE_BBDEV_MAX_CODE_BLOCKS) {
302 		printf("Too many segments (code blocks defined): %u, max %d!\n",
303 				*nb_ops, RTE_BBDEV_MAX_CODE_BLOCKS);
304 		return -1;
305 	}
306 
307 	if (sscanf(key_token + strlen(prefix), "%u", &id) != 1) {
308 		printf("Missing ID of %s\n", prefix);
309 		return -1;
310 	}
311 	if (id != *nb_ops) {
312 		printf(
313 			"Please order data entries sequentially, i.e. %s0, %s1, ...\n",
314 				prefix, prefix);
315 		return -1;
316 	}
317 
318 	/* Clear new op data struct */
319 	memset(op_data + *nb_ops, 0, sizeof(struct op_data_buf));
320 
321 	ret = parse_values(token, &data, &data_length);
322 	if (!ret) {
323 		op_data[*nb_ops].addr = data;
324 		op_data[*nb_ops].length = data_length;
325 		++(*nb_ops);
326 	}
327 
328 	return ret;
329 }
330 
331 /* parses turbo decoder parameters and assigns to global variable */
332 static int
333 parse_decoder_params(const char *key_token, char *token,
334 		struct test_bbdev_vector *vector)
335 {
336 	int ret = 0, status = 0;
337 	uint32_t op_flags = 0;
338 	char *err = NULL;
339 
340 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
341 
342 	/* compare keys */
343 	if (starts_with(key_token, op_data_prefixes[DATA_INPUT]))
344 		ret = parse_data_entry(key_token, token, vector,
345 				DATA_INPUT, op_data_prefixes[DATA_INPUT]);
346 
347 	else if (starts_with(key_token, op_data_prefixes[DATA_SOFT_OUTPUT]))
348 		ret = parse_data_entry(key_token, token, vector,
349 				DATA_SOFT_OUTPUT,
350 				op_data_prefixes[DATA_SOFT_OUTPUT]);
351 
352 	else if (starts_with(key_token, op_data_prefixes[DATA_HARD_OUTPUT]))
353 		ret = parse_data_entry(key_token, token, vector,
354 				DATA_HARD_OUTPUT,
355 				op_data_prefixes[DATA_HARD_OUTPUT]);
356 	else if (!strcmp(key_token, "e")) {
357 		vector->mask |= TEST_BBDEV_VF_E;
358 		turbo_dec->cb_params.e = (uint32_t) strtoul(token, &err, 0);
359 	} else if (!strcmp(key_token, "ea")) {
360 		vector->mask |= TEST_BBDEV_VF_EA;
361 		turbo_dec->tb_params.ea = (uint32_t) strtoul(token, &err, 0);
362 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
363 	} else if (!strcmp(key_token, "eb")) {
364 		vector->mask |= TEST_BBDEV_VF_EB;
365 		turbo_dec->tb_params.eb = (uint32_t) strtoul(token, &err, 0);
366 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
367 	} else if (!strcmp(key_token, "k")) {
368 		vector->mask |= TEST_BBDEV_VF_K;
369 		turbo_dec->cb_params.k = (uint16_t) strtoul(token, &err, 0);
370 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
371 	} else if (!strcmp(key_token, "k_pos")) {
372 		vector->mask |= TEST_BBDEV_VF_K_POS;
373 		turbo_dec->tb_params.k_pos = (uint16_t) strtoul(token, &err, 0);
374 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
375 	} else if (!strcmp(key_token, "k_neg")) {
376 		vector->mask |= TEST_BBDEV_VF_K_NEG;
377 		turbo_dec->tb_params.k_neg = (uint16_t) strtoul(token, &err, 0);
378 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
379 	} else if (!strcmp(key_token, "c")) {
380 		vector->mask |= TEST_BBDEV_VF_C;
381 		turbo_dec->tb_params.c = (uint16_t) strtoul(token, &err, 0);
382 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
383 	} else if (!strcmp(key_token, "c_neg")) {
384 		vector->mask |= TEST_BBDEV_VF_C_NEG;
385 		turbo_dec->tb_params.c_neg = (uint16_t) strtoul(token, &err, 0);
386 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
387 	} else if (!strcmp(key_token, "cab")) {
388 		vector->mask |= TEST_BBDEV_VF_CAB;
389 		turbo_dec->tb_params.cab = (uint8_t) strtoul(token, &err, 0);
390 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
391 	} else if (!strcmp(key_token, "rv_index")) {
392 		vector->mask |= TEST_BBDEV_VF_RV_INDEX;
393 		turbo_dec->rv_index = (uint8_t) strtoul(token, &err, 0);
394 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
395 	} else if (!strcmp(key_token, "iter_max")) {
396 		vector->mask |= TEST_BBDEV_VF_ITER_MAX;
397 		turbo_dec->iter_max = (uint8_t) strtoul(token, &err, 0);
398 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
399 	} else if (!strcmp(key_token, "iter_min")) {
400 		vector->mask |= TEST_BBDEV_VF_ITER_MIN;
401 		turbo_dec->iter_min = (uint8_t) strtoul(token, &err, 0);
402 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
403 	} else if (!strcmp(key_token, "expected_iter_count")) {
404 		vector->mask |= TEST_BBDEV_VF_EXPECTED_ITER_COUNT;
405 		turbo_dec->iter_count = (uint8_t) strtoul(token, &err, 0);
406 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
407 	} else if (!strcmp(key_token, "ext_scale")) {
408 		vector->mask |= TEST_BBDEV_VF_EXT_SCALE;
409 		turbo_dec->ext_scale = (uint8_t) strtoul(token, &err, 0);
410 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
411 	} else if (!strcmp(key_token, "num_maps")) {
412 		vector->mask |= TEST_BBDEV_VF_NUM_MAPS;
413 		turbo_dec->num_maps = (uint8_t) strtoul(token, &err, 0);
414 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
415 	} else if (!strcmp(key_token, "r")) {
416 		vector->mask |= TEST_BBDEV_VF_R;
417 		turbo_dec->tb_params.r = (uint8_t) strtoul(token, &err, 0);
418 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
419 	} else if (!strcmp(key_token, "code_block_mode")) {
420 		vector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;
421 		turbo_dec->code_block_mode = (uint8_t) strtoul(token, &err, 0);
422 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
423 	} else if (!strcmp(key_token, "op_flags")) {
424 		vector->mask |= TEST_BBDEV_VF_OP_FLAGS;
425 		ret = parse_turbo_flags(token, &op_flags,
426 			vector->op_type);
427 		if (!ret)
428 			turbo_dec->op_flags = op_flags;
429 	} else if (!strcmp(key_token, "expected_status")) {
430 		vector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;
431 		ret = parse_expected_status(token, &status, vector->op_type);
432 		if (!ret)
433 			vector->expected_status = status;
434 	} else {
435 		printf("Not valid dec key: '%s'\n", key_token);
436 		return -1;
437 	}
438 
439 	if (ret != 0) {
440 		printf("Failed with convert '%s\t%s'\n", key_token, token);
441 		return -1;
442 	}
443 
444 	return 0;
445 }
446 
447 /* parses turbo encoder parameters and assigns to global variable */
448 static int
449 parse_encoder_params(const char *key_token, char *token,
450 		struct test_bbdev_vector *vector)
451 {
452 	int ret = 0, status = 0;
453 	uint32_t op_flags = 0;
454 	char *err = NULL;
455 
456 
457 	struct rte_bbdev_op_turbo_enc *turbo_enc = &vector->turbo_enc;
458 
459 	if (starts_with(key_token, op_data_prefixes[DATA_INPUT]))
460 		ret = parse_data_entry(key_token, token, vector,
461 				DATA_INPUT, op_data_prefixes[DATA_INPUT]);
462 	else if (starts_with(key_token, "output"))
463 		ret = parse_data_entry(key_token, token, vector,
464 				DATA_HARD_OUTPUT, "output");
465 	else if (!strcmp(key_token, "e")) {
466 		vector->mask |= TEST_BBDEV_VF_E;
467 		turbo_enc->cb_params.e = (uint32_t) strtoul(token, &err, 0);
468 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
469 	} else if (!strcmp(key_token, "ea")) {
470 		vector->mask |= TEST_BBDEV_VF_EA;
471 		turbo_enc->tb_params.ea = (uint32_t) strtoul(token, &err, 0);
472 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
473 	} else if (!strcmp(key_token, "eb")) {
474 		vector->mask |= TEST_BBDEV_VF_EB;
475 		turbo_enc->tb_params.eb = (uint32_t) strtoul(token, &err, 0);
476 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
477 	} else if (!strcmp(key_token, "k")) {
478 		vector->mask |= TEST_BBDEV_VF_K;
479 		turbo_enc->cb_params.k = (uint16_t) strtoul(token, &err, 0);
480 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
481 	} else if (!strcmp(key_token, "k_neg")) {
482 		vector->mask |= TEST_BBDEV_VF_K_NEG;
483 		turbo_enc->tb_params.k_neg = (uint16_t) strtoul(token, &err, 0);
484 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
485 	} else if (!strcmp(key_token, "k_pos")) {
486 		vector->mask |= TEST_BBDEV_VF_K_POS;
487 		turbo_enc->tb_params.k_pos = (uint16_t) strtoul(token, &err, 0);
488 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
489 	} else if (!strcmp(key_token, "c_neg")) {
490 		vector->mask |= TEST_BBDEV_VF_C_NEG;
491 		turbo_enc->tb_params.c_neg = (uint8_t) strtoul(token, &err, 0);
492 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
493 	} else if (!strcmp(key_token, "c")) {
494 		vector->mask |= TEST_BBDEV_VF_C;
495 		turbo_enc->tb_params.c = (uint8_t) strtoul(token, &err, 0);
496 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
497 	} else if (!strcmp(key_token, "cab")) {
498 		vector->mask |= TEST_BBDEV_VF_CAB;
499 		turbo_enc->tb_params.cab = (uint8_t) strtoul(token, &err, 0);
500 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
501 	} else if (!strcmp(key_token, "rv_index")) {
502 		vector->mask |= TEST_BBDEV_VF_RV_INDEX;
503 		turbo_enc->rv_index = (uint8_t) strtoul(token, &err, 0);
504 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
505 	} else if (!strcmp(key_token, "ncb")) {
506 		vector->mask |= TEST_BBDEV_VF_NCB;
507 		turbo_enc->cb_params.ncb = (uint16_t) strtoul(token, &err, 0);
508 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
509 	} else if (!strcmp(key_token, "ncb_neg")) {
510 		vector->mask |= TEST_BBDEV_VF_NCB_NEG;
511 		turbo_enc->tb_params.ncb_neg =
512 				(uint16_t) strtoul(token, &err, 0);
513 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
514 	} else if (!strcmp(key_token, "ncb_pos")) {
515 		vector->mask |= TEST_BBDEV_VF_NCB_POS;
516 		turbo_enc->tb_params.ncb_pos =
517 				(uint16_t) strtoul(token, &err, 0);
518 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
519 	} else if (!strcmp(key_token, "r")) {
520 		vector->mask |= TEST_BBDEV_VF_R;
521 		turbo_enc->tb_params.r = (uint8_t) strtoul(token, &err, 0);
522 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
523 	} else if (!strcmp(key_token, "code_block_mode")) {
524 		vector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;
525 		turbo_enc->code_block_mode = (uint8_t) strtoul(token, &err, 0);
526 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
527 	} else if (!strcmp(key_token, "op_flags")) {
528 		vector->mask |= TEST_BBDEV_VF_OP_FLAGS;
529 		ret = parse_turbo_flags(token, &op_flags,
530 				vector->op_type);
531 		if (!ret)
532 			turbo_enc->op_flags = op_flags;
533 	} else if (!strcmp(key_token, "expected_status")) {
534 		vector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;
535 		ret = parse_expected_status(token, &status, vector->op_type);
536 		if (!ret)
537 			vector->expected_status = status;
538 	} else {
539 		printf("Not valid enc key: '%s'\n", key_token);
540 		return -1;
541 	}
542 
543 	if (ret != 0) {
544 		printf("Failed with convert '%s\t%s'\n", key_token, token);
545 		return -1;
546 	}
547 
548 	return 0;
549 }
550 
551 /* checks the type of key and assigns data */
552 static int
553 parse_entry(char *entry, struct test_bbdev_vector *vector)
554 {
555 	int ret = 0;
556 	char *token, *key_token;
557 	enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_NONE;
558 
559 	if (entry == NULL) {
560 		printf("Expected entry value\n");
561 		return -1;
562 	}
563 
564 	/* get key */
565 	token = strtok(entry, ENTRY_DELIMITER);
566 	key_token = token;
567 	/* get values for key */
568 	token = strtok(NULL, ENTRY_DELIMITER);
569 
570 	if (key_token == NULL || token == NULL) {
571 		printf("Expected 'key = values' but was '%.40s'..\n", entry);
572 		return -1;
573 	}
574 	trim_space(key_token);
575 
576 	/* first key_token has to specify type of operation */
577 	if (vector->op_type == RTE_BBDEV_OP_NONE) {
578 		if (!strcmp(key_token, "op_type")) {
579 			ret = op_turbo_type_strtol(token, &op_type);
580 			if (!ret)
581 				vector->op_type = op_type;
582 			return (!ret) ? 0 : -1;
583 		}
584 		printf("First key_token (%s) does not specify op_type\n",
585 				key_token);
586 		return -1;
587 	}
588 
589 	/* compare keys */
590 	if (vector->op_type == RTE_BBDEV_OP_TURBO_DEC) {
591 		if (parse_decoder_params(key_token, token, vector) == -1)
592 			return -1;
593 	} else if (vector->op_type == RTE_BBDEV_OP_TURBO_ENC) {
594 		if (parse_encoder_params(key_token, token, vector) == -1)
595 			return -1;
596 	}
597 
598 	return 0;
599 }
600 
601 static int
602 check_decoder_segments(struct test_bbdev_vector *vector)
603 {
604 	unsigned char i;
605 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
606 
607 	if (vector->entries[DATA_INPUT].nb_segments == 0)
608 		return -1;
609 
610 	for (i = 0; i < vector->entries[DATA_INPUT].nb_segments; i++)
611 		if (vector->entries[DATA_INPUT].segments[i].addr == NULL)
612 			return -1;
613 
614 	if (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0)
615 		return -1;
616 
617 	for (i = 0; i < vector->entries[DATA_HARD_OUTPUT].nb_segments;
618 			i++)
619 		if (vector->entries[DATA_HARD_OUTPUT].segments[i].addr == NULL)
620 			return -1;
621 
622 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_SOFT_OUTPUT) &&
623 			(vector->entries[DATA_SOFT_OUTPUT].nb_segments == 0))
624 		return -1;
625 
626 	for (i = 0; i < vector->entries[DATA_SOFT_OUTPUT].nb_segments;
627 			i++)
628 		if (vector->entries[DATA_SOFT_OUTPUT].segments[i].addr == NULL)
629 			return -1;
630 
631 	return 0;
632 }
633 
634 static int
635 check_decoder_llr_spec(struct test_bbdev_vector *vector)
636 {
637 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
638 
639 	/* Check input LLR sign formalism specification */
640 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN) &&
641 			(turbo_dec->op_flags &
642 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN)) {
643 		printf(
644 			"Both positive and negative LLR input flags were set!\n");
645 		return -1;
646 	}
647 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN) &&
648 			!(turbo_dec->op_flags &
649 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN)) {
650 		printf(
651 			"WARNING: input LLR sign formalism was not specified and will be set to negative LLR for '1' bit\n");
652 		turbo_dec->op_flags |= RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN;
653 	}
654 
655 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_SOFT_OUTPUT))
656 		return 0;
657 
658 	/* Check output LLR sign formalism specification */
659 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT) &&
660 			(turbo_dec->op_flags &
661 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT)) {
662 		printf(
663 			"Both positive and negative LLR output flags were set!\n");
664 		return -1;
665 	}
666 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT) &&
667 			!(turbo_dec->op_flags &
668 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT)) {
669 		printf(
670 			"WARNING: soft output LLR sign formalism was not specified and will be set to negative LLR for '1' bit\n");
671 		turbo_dec->op_flags |=
672 				RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT;
673 	}
674 
675 	return 0;
676 }
677 
678 /* checks decoder parameters */
679 static int
680 check_decoder(struct test_bbdev_vector *vector)
681 {
682 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
683 	const int mask = vector->mask;
684 
685 	if (check_decoder_segments(vector) < 0)
686 		return -1;
687 
688 	if (check_decoder_llr_spec(vector) < 0)
689 		return -1;
690 
691 	/* Check which params were set */
692 	if (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {
693 		printf(
694 			"WARNING: code_block_mode was not specified in vector file and will be set to 1 (0 - TB Mode, 1 - CB mode)\n");
695 		turbo_dec->code_block_mode = 1;
696 	}
697 	if (turbo_dec->code_block_mode == 0) {
698 		if (!(mask & TEST_BBDEV_VF_EA))
699 			printf(
700 				"WARNING: ea was not specified in vector file and will be set to 0\n");
701 		if (!(mask & TEST_BBDEV_VF_EB))
702 			printf(
703 				"WARNING: eb was not specified in vector file and will be set to 0\n");
704 		if (!(mask & TEST_BBDEV_VF_K_NEG))
705 			printf(
706 				"WARNING: k_neg was not specified in vector file and will be set to 0\n");
707 		if (!(mask & TEST_BBDEV_VF_K_POS))
708 			printf(
709 				"WARNING: k_pos was not specified in vector file and will be set to 0\n");
710 		if (!(mask & TEST_BBDEV_VF_C_NEG))
711 			printf(
712 				"WARNING: c_neg was not specified in vector file and will be set to 0\n");
713 		if (!(mask & TEST_BBDEV_VF_C)) {
714 			printf(
715 				"WARNING: c was not specified in vector file and will be set to 1\n");
716 			turbo_dec->tb_params.c = 1;
717 		}
718 		if (!(mask & TEST_BBDEV_VF_CAB))
719 			printf(
720 				"WARNING: cab was not specified in vector file and will be set to 0\n");
721 		if (!(mask & TEST_BBDEV_VF_R))
722 			printf(
723 				"WARNING: r was not specified in vector file and will be set to 0\n");
724 	} else {
725 		if (!(mask & TEST_BBDEV_VF_E))
726 			printf(
727 				"WARNING: e was not specified in vector file and will be set to 0\n");
728 		if (!(mask & TEST_BBDEV_VF_K))
729 			printf(
730 				"WARNING: k was not specified in vector file and will be set to 0\n");
731 	}
732 	if (!(mask & TEST_BBDEV_VF_RV_INDEX))
733 		printf(
734 			"WARNING: rv_index was not specified in vector file and will be set to 0\n");
735 	if (!(mask & TEST_BBDEV_VF_ITER_MIN))
736 		printf(
737 			"WARNING: iter_min was not specified in vector file and will be set to 0\n");
738 	if (!(mask & TEST_BBDEV_VF_ITER_MAX))
739 		printf(
740 			"WARNING: iter_max was not specified in vector file and will be set to 0\n");
741 	if (!(mask & TEST_BBDEV_VF_EXPECTED_ITER_COUNT))
742 		printf(
743 			"WARNING: expected_iter_count was not specified in vector file and iter_count will not be validated\n");
744 	if (!(mask & TEST_BBDEV_VF_EXT_SCALE))
745 		printf(
746 			"WARNING: ext_scale was not specified in vector file and will be set to 0\n");
747 	if (!(mask & TEST_BBDEV_VF_OP_FLAGS)) {
748 		printf(
749 			"WARNING: op_flags was not specified in vector file and capabilities will not be validated\n");
750 		turbo_dec->num_maps = 0;
751 	} else if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_MAP_DEC) &&
752 			mask & TEST_BBDEV_VF_NUM_MAPS) {
753 		printf(
754 			"WARNING: RTE_BBDEV_TURBO_MAP_DEC was not set in vector file and num_maps will be set to 0\n");
755 		turbo_dec->num_maps = 0;
756 	}
757 	if (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))
758 		printf(
759 			"WARNING: expected_status was not specified in vector file and will be set to 0\n");
760 	return 0;
761 }
762 
763 /* checks encoder parameters */
764 static int
765 check_encoder(struct test_bbdev_vector *vector)
766 {
767 	unsigned char i;
768 	const int mask = vector->mask;
769 
770 	if (vector->entries[DATA_INPUT].nb_segments == 0)
771 		return -1;
772 
773 	for (i = 0; i < vector->entries[DATA_INPUT].nb_segments; i++)
774 		if (vector->entries[DATA_INPUT].segments[i].addr == NULL)
775 			return -1;
776 
777 	if (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0)
778 		return -1;
779 
780 	for (i = 0; i < vector->entries[DATA_HARD_OUTPUT].nb_segments; i++)
781 		if (vector->entries[DATA_HARD_OUTPUT].segments[i].addr == NULL)
782 			return -1;
783 
784 	if (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {
785 		printf(
786 			"WARNING: code_block_mode was not specified in vector file and will be set to 1\n");
787 		vector->turbo_enc.code_block_mode = 1;
788 	}
789 	if (vector->turbo_enc.code_block_mode == 0) {
790 		if (!(mask & TEST_BBDEV_VF_EA) && (vector->turbo_enc.op_flags &
791 				RTE_BBDEV_TURBO_RATE_MATCH))
792 			printf(
793 				"WARNING: ea was not specified in vector file and will be set to 0\n");
794 		if (!(mask & TEST_BBDEV_VF_EB) && (vector->turbo_enc.op_flags &
795 				RTE_BBDEV_TURBO_RATE_MATCH))
796 			printf(
797 				"WARNING: eb was not specified in vector file and will be set to 0\n");
798 		if (!(mask & TEST_BBDEV_VF_K_NEG))
799 			printf(
800 				"WARNING: k_neg was not specified in vector file and will be set to 0\n");
801 		if (!(mask & TEST_BBDEV_VF_K_POS))
802 			printf(
803 				"WARNING: k_pos was not specified in vector file and will be set to 0\n");
804 		if (!(mask & TEST_BBDEV_VF_C_NEG))
805 			printf(
806 				"WARNING: c_neg was not specified in vector file and will be set to 0\n");
807 		if (!(mask & TEST_BBDEV_VF_C)) {
808 			printf(
809 				"WARNING: c was not specified in vector file and will be set to 1\n");
810 			vector->turbo_enc.tb_params.c = 1;
811 		}
812 		if (!(mask & TEST_BBDEV_VF_CAB) && (vector->turbo_enc.op_flags &
813 				RTE_BBDEV_TURBO_RATE_MATCH))
814 			printf(
815 				"WARNING: cab was not specified in vector file and will be set to 0\n");
816 		if (!(mask & TEST_BBDEV_VF_NCB_NEG))
817 			printf(
818 				"WARNING: ncb_neg was not specified in vector file and will be set to 0\n");
819 		if (!(mask & TEST_BBDEV_VF_NCB_POS))
820 			printf(
821 				"WARNING: ncb_pos was not specified in vector file and will be set to 0\n");
822 		if (!(mask & TEST_BBDEV_VF_R))
823 			printf(
824 				"WARNING: r was not specified in vector file and will be set to 0\n");
825 	} else {
826 		if (!(mask & TEST_BBDEV_VF_E) && (vector->turbo_enc.op_flags &
827 				RTE_BBDEV_TURBO_RATE_MATCH))
828 			printf(
829 				"WARNING: e was not specified in vector file and will be set to 0\n");
830 		if (!(mask & TEST_BBDEV_VF_K))
831 			printf(
832 				"WARNING: k was not specified in vector file and will be set to 0\n");
833 		if (!(mask & TEST_BBDEV_VF_NCB))
834 			printf(
835 				"WARNING: ncb was not specified in vector file and will be set to 0\n");
836 	}
837 	if (!(mask & TEST_BBDEV_VF_RV_INDEX))
838 		printf(
839 			"WARNING: rv_index was not specified in vector file and will be set to 0\n");
840 	if (!(mask & TEST_BBDEV_VF_OP_FLAGS))
841 		printf(
842 			"WARNING: op_flags was not specified in vector file and capabilities will not be validated\n");
843 	if (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))
844 		printf(
845 			"WARNING: expected_status was not specified in vector file and will be set to 0\n");
846 
847 	return 0;
848 }
849 
850 static int
851 bbdev_check_vector(struct test_bbdev_vector *vector)
852 {
853 	if (vector->op_type == RTE_BBDEV_OP_TURBO_DEC) {
854 		if (check_decoder(vector) == -1)
855 			return -1;
856 	} else if (vector->op_type == RTE_BBDEV_OP_TURBO_ENC) {
857 		if (check_encoder(vector) == -1)
858 			return -1;
859 	} else if (vector->op_type != RTE_BBDEV_OP_NONE) {
860 		printf("Vector was not filled\n");
861 		return -1;
862 	}
863 
864 	return 0;
865 }
866 
867 int
868 test_bbdev_vector_read(const char *filename,
869 		struct test_bbdev_vector *vector)
870 {
871 	int ret = 0;
872 	size_t len = 0;
873 
874 	FILE *fp = NULL;
875 	char *line = NULL;
876 	char *entry = NULL;
877 
878 	fp = fopen(filename, "r");
879 	if (fp == NULL) {
880 		printf("File %s does not exist\n", filename);
881 		return -1;
882 	}
883 
884 	while (getline(&line, &len, fp) != -1) {
885 
886 		/* ignore comments and new lines */
887 		if (line[0] == '#' || line[0] == '/' || line[0] == '\n'
888 			|| line[0] == '\r')
889 			continue;
890 
891 		trim_space(line);
892 
893 		/* buffer for multiline */
894 		entry = realloc(entry, strlen(line) + 1);
895 		if (entry == NULL) {
896 			printf("Fail to realloc %zu bytes\n", strlen(line) + 1);
897 			ret = -ENOMEM;
898 			goto exit;
899 		}
900 
901 		strcpy(entry, line);
902 
903 		/* check if entry ends with , or = */
904 		if (entry[strlen(entry) - 1] == ','
905 			|| entry[strlen(entry) - 1] == '=') {
906 			while (getline(&line, &len, fp) != -1) {
907 				trim_space(line);
908 
909 				/* extend entry about length of new line */
910 				char *entry_extended = realloc(entry,
911 						strlen(line) +
912 						strlen(entry) + 1);
913 
914 				if (entry_extended == NULL) {
915 					printf("Fail to allocate %zu bytes\n",
916 							strlen(line) +
917 							strlen(entry) + 1);
918 					ret = -ENOMEM;
919 					goto exit;
920 				}
921 
922 				entry = entry_extended;
923 				/* entry has been allocated accordingly */
924 				strcpy(&entry[strlen(entry)], line);
925 
926 				if (entry[strlen(entry) - 1] != ',')
927 					break;
928 			}
929 		}
930 		ret = parse_entry(entry, vector);
931 		if (ret != 0) {
932 			printf("An error occurred while parsing!\n");
933 			goto exit;
934 		}
935 	}
936 	ret = bbdev_check_vector(vector);
937 	if (ret != 0)
938 		printf("An error occurred while checking!\n");
939 
940 exit:
941 	fclose(fp);
942 	free(line);
943 	free(entry);
944 
945 	return ret;
946 }
947