xref: /dpdk/app/test-bbdev/test_bbdev_vector.c (revision 08aa6271c86a561b66c6dd91f9a54fa2f12bc859)
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, "code_block_mode")) {
416 		vector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;
417 		turbo_dec->code_block_mode = (uint8_t) strtoul(token, &err, 0);
418 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
419 	} else if (!strcmp(key_token, "op_flags")) {
420 		vector->mask |= TEST_BBDEV_VF_OP_FLAGS;
421 		ret = parse_turbo_flags(token, &op_flags,
422 			vector->op_type);
423 		if (!ret)
424 			turbo_dec->op_flags = op_flags;
425 	} else if (!strcmp(key_token, "expected_status")) {
426 		vector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;
427 		ret = parse_expected_status(token, &status, vector->op_type);
428 		if (!ret)
429 			vector->expected_status = status;
430 	} else {
431 		printf("Not valid dec key: '%s'\n", key_token);
432 		return -1;
433 	}
434 
435 	if (ret != 0) {
436 		printf("Failed with convert '%s\t%s'\n", key_token, token);
437 		return -1;
438 	}
439 
440 	return 0;
441 }
442 
443 /* parses turbo encoder parameters and assigns to global variable */
444 static int
445 parse_encoder_params(const char *key_token, char *token,
446 		struct test_bbdev_vector *vector)
447 {
448 	int ret = 0, status = 0;
449 	uint32_t op_flags = 0;
450 	char *err = NULL;
451 
452 
453 	struct rte_bbdev_op_turbo_enc *turbo_enc = &vector->turbo_enc;
454 
455 	if (starts_with(key_token, op_data_prefixes[DATA_INPUT]))
456 		ret = parse_data_entry(key_token, token, vector,
457 				DATA_INPUT, op_data_prefixes[DATA_INPUT]);
458 	else if (starts_with(key_token, "output"))
459 		ret = parse_data_entry(key_token, token, vector,
460 				DATA_HARD_OUTPUT, "output");
461 	else if (!strcmp(key_token, "e")) {
462 		vector->mask |= TEST_BBDEV_VF_E;
463 		turbo_enc->cb_params.e = (uint32_t) strtoul(token, &err, 0);
464 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
465 	} else if (!strcmp(key_token, "ea")) {
466 		vector->mask |= TEST_BBDEV_VF_EA;
467 		turbo_enc->tb_params.ea = (uint32_t) strtoul(token, &err, 0);
468 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
469 	} else if (!strcmp(key_token, "eb")) {
470 		vector->mask |= TEST_BBDEV_VF_EB;
471 		turbo_enc->tb_params.eb = (uint32_t) strtoul(token, &err, 0);
472 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
473 	} else if (!strcmp(key_token, "k")) {
474 		vector->mask |= TEST_BBDEV_VF_K;
475 		turbo_enc->cb_params.k = (uint16_t) strtoul(token, &err, 0);
476 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
477 	} else if (!strcmp(key_token, "k_neg")) {
478 		vector->mask |= TEST_BBDEV_VF_K_NEG;
479 		turbo_enc->tb_params.k_neg = (uint16_t) strtoul(token, &err, 0);
480 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
481 	} else if (!strcmp(key_token, "k_pos")) {
482 		vector->mask |= TEST_BBDEV_VF_K_POS;
483 		turbo_enc->tb_params.k_pos = (uint16_t) strtoul(token, &err, 0);
484 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
485 	} else if (!strcmp(key_token, "c_neg")) {
486 		vector->mask |= TEST_BBDEV_VF_C_NEG;
487 		turbo_enc->tb_params.c_neg = (uint8_t) strtoul(token, &err, 0);
488 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
489 	} else if (!strcmp(key_token, "c")) {
490 		vector->mask |= TEST_BBDEV_VF_C;
491 		turbo_enc->tb_params.c = (uint8_t) strtoul(token, &err, 0);
492 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
493 	} else if (!strcmp(key_token, "cab")) {
494 		vector->mask |= TEST_BBDEV_VF_CAB;
495 		turbo_enc->tb_params.cab = (uint8_t) strtoul(token, &err, 0);
496 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
497 	} else if (!strcmp(key_token, "rv_index")) {
498 		vector->mask |= TEST_BBDEV_VF_RV_INDEX;
499 		turbo_enc->rv_index = (uint8_t) strtoul(token, &err, 0);
500 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
501 	} else if (!strcmp(key_token, "ncb")) {
502 		vector->mask |= TEST_BBDEV_VF_NCB;
503 		turbo_enc->cb_params.ncb = (uint16_t) strtoul(token, &err, 0);
504 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
505 	} else if (!strcmp(key_token, "ncb_neg")) {
506 		vector->mask |= TEST_BBDEV_VF_NCB_NEG;
507 		turbo_enc->tb_params.ncb_neg =
508 				(uint16_t) strtoul(token, &err, 0);
509 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
510 	} else if (!strcmp(key_token, "ncb_pos")) {
511 		vector->mask |= TEST_BBDEV_VF_NCB_POS;
512 		turbo_enc->tb_params.ncb_pos =
513 				(uint16_t) strtoul(token, &err, 0);
514 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
515 	} else if (!strcmp(key_token, "r")) {
516 		vector->mask |= TEST_BBDEV_VF_R;
517 		turbo_enc->tb_params.r = (uint8_t) strtoul(token, &err, 0);
518 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
519 	} else if (!strcmp(key_token, "code_block_mode")) {
520 		vector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;
521 		turbo_enc->code_block_mode = (uint8_t) strtoul(token, &err, 0);
522 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
523 	} else if (!strcmp(key_token, "op_flags")) {
524 		vector->mask |= TEST_BBDEV_VF_OP_FLAGS;
525 		ret = parse_turbo_flags(token, &op_flags,
526 				vector->op_type);
527 		if (!ret)
528 			turbo_enc->op_flags = op_flags;
529 	} else if (!strcmp(key_token, "expected_status")) {
530 		vector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;
531 		ret = parse_expected_status(token, &status, vector->op_type);
532 		if (!ret)
533 			vector->expected_status = status;
534 	} else {
535 		printf("Not valid enc key: '%s'\n", key_token);
536 		return -1;
537 	}
538 
539 	if (ret != 0) {
540 		printf("Failed with convert '%s\t%s'\n", key_token, token);
541 		return -1;
542 	}
543 
544 	return 0;
545 }
546 
547 /* checks the type of key and assigns data */
548 static int
549 parse_entry(char *entry, struct test_bbdev_vector *vector)
550 {
551 	int ret = 0;
552 	char *token, *key_token;
553 	enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_NONE;
554 
555 	if (entry == NULL) {
556 		printf("Expected entry value\n");
557 		return -1;
558 	}
559 
560 	/* get key */
561 	token = strtok(entry, ENTRY_DELIMITER);
562 	key_token = token;
563 	/* get values for key */
564 	token = strtok(NULL, ENTRY_DELIMITER);
565 
566 	if (key_token == NULL || token == NULL) {
567 		printf("Expected 'key = values' but was '%.40s'..\n", entry);
568 		return -1;
569 	}
570 	trim_space(key_token);
571 
572 	/* first key_token has to specify type of operation */
573 	if (vector->op_type == RTE_BBDEV_OP_NONE) {
574 		if (!strcmp(key_token, "op_type")) {
575 			ret = op_turbo_type_strtol(token, &op_type);
576 			if (!ret)
577 				vector->op_type = op_type;
578 			return (!ret) ? 0 : -1;
579 		}
580 		printf("First key_token (%s) does not specify op_type\n",
581 				key_token);
582 		return -1;
583 	}
584 
585 	/* compare keys */
586 	if (vector->op_type == RTE_BBDEV_OP_TURBO_DEC) {
587 		if (parse_decoder_params(key_token, token, vector) == -1)
588 			return -1;
589 	} else if (vector->op_type == RTE_BBDEV_OP_TURBO_ENC) {
590 		if (parse_encoder_params(key_token, token, vector) == -1)
591 			return -1;
592 	}
593 
594 	return 0;
595 }
596 
597 static int
598 check_decoder_segments(struct test_bbdev_vector *vector)
599 {
600 	unsigned char i;
601 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
602 
603 	if (vector->entries[DATA_INPUT].nb_segments == 0)
604 		return -1;
605 
606 	for (i = 0; i < vector->entries[DATA_INPUT].nb_segments; i++)
607 		if (vector->entries[DATA_INPUT].segments[i].addr == NULL)
608 			return -1;
609 
610 	if (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0)
611 		return -1;
612 
613 	for (i = 0; i < vector->entries[DATA_HARD_OUTPUT].nb_segments;
614 			i++)
615 		if (vector->entries[DATA_HARD_OUTPUT].segments[i].addr == NULL)
616 			return -1;
617 
618 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_SOFT_OUTPUT) &&
619 			(vector->entries[DATA_SOFT_OUTPUT].nb_segments == 0))
620 		return -1;
621 
622 	for (i = 0; i < vector->entries[DATA_SOFT_OUTPUT].nb_segments;
623 			i++)
624 		if (vector->entries[DATA_SOFT_OUTPUT].segments[i].addr == NULL)
625 			return -1;
626 
627 	return 0;
628 }
629 
630 static int
631 check_decoder_llr_spec(struct test_bbdev_vector *vector)
632 {
633 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
634 
635 	/* Check input LLR sign formalism specification */
636 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN) &&
637 			(turbo_dec->op_flags &
638 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN)) {
639 		printf(
640 			"Both positive and negative LLR input flags were set!\n");
641 		return -1;
642 	}
643 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN) &&
644 			!(turbo_dec->op_flags &
645 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN)) {
646 		printf(
647 			"WARNING: input LLR sign formalism was not specified and will be set to negative LLR for '1' bit\n");
648 		turbo_dec->op_flags |= RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN;
649 	}
650 
651 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_SOFT_OUTPUT))
652 		return 0;
653 
654 	/* Check output LLR sign formalism specification */
655 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT) &&
656 			(turbo_dec->op_flags &
657 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT)) {
658 		printf(
659 			"Both positive and negative LLR output flags were set!\n");
660 		return -1;
661 	}
662 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT) &&
663 			!(turbo_dec->op_flags &
664 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT)) {
665 		printf(
666 			"WARNING: soft output LLR sign formalism was not specified and will be set to negative LLR for '1' bit\n");
667 		turbo_dec->op_flags |=
668 				RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT;
669 	}
670 
671 	return 0;
672 }
673 
674 /* checks decoder parameters */
675 static int
676 check_decoder(struct test_bbdev_vector *vector)
677 {
678 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
679 	const int mask = vector->mask;
680 
681 	if (check_decoder_segments(vector) < 0)
682 		return -1;
683 
684 	if (check_decoder_llr_spec(vector) < 0)
685 		return -1;
686 
687 	/* Check which params were set */
688 	if (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {
689 		printf(
690 			"WARNING: code_block_mode was not specified in vector file and will be set to 1 (0 - TB Mode, 1 - CB mode)\n");
691 		turbo_dec->code_block_mode = 1;
692 	}
693 	if (turbo_dec->code_block_mode == 0) {
694 		if (!(mask & TEST_BBDEV_VF_EA))
695 			printf(
696 				"WARNING: ea was not specified in vector file and will be set to 0\n");
697 		if (!(mask & TEST_BBDEV_VF_EB))
698 			printf(
699 				"WARNING: eb was not specified in vector file and will be set to 0\n");
700 		if (!(mask & TEST_BBDEV_VF_K_NEG))
701 			printf(
702 				"WARNING: k_neg was not specified in vector file and will be set to 0\n");
703 		if (!(mask & TEST_BBDEV_VF_K_POS))
704 			printf(
705 				"WARNING: k_pos was not specified in vector file and will be set to 0\n");
706 		if (!(mask & TEST_BBDEV_VF_C_NEG))
707 			printf(
708 				"WARNING: c_neg was not specified in vector file and will be set to 0\n");
709 		if (!(mask & TEST_BBDEV_VF_C)) {
710 			printf(
711 				"WARNING: c was not specified in vector file and will be set to 1\n");
712 			turbo_dec->tb_params.c = 1;
713 		}
714 		if (!(mask & TEST_BBDEV_VF_CAB))
715 			printf(
716 				"WARNING: cab was not specified in vector file and will be set to 0\n");
717 	} else {
718 		if (!(mask & TEST_BBDEV_VF_E))
719 			printf(
720 				"WARNING: e was not specified in vector file and will be set to 0\n");
721 		if (!(mask & TEST_BBDEV_VF_K))
722 			printf(
723 				"WARNING: k was not specified in vector file and will be set to 0\n");
724 	}
725 	if (!(mask & TEST_BBDEV_VF_RV_INDEX))
726 		printf(
727 			"WARNING: rv_index was not specified in vector file and will be set to 0\n");
728 	if (!(mask & TEST_BBDEV_VF_ITER_MIN))
729 		printf(
730 			"WARNING: iter_min was not specified in vector file and will be set to 0\n");
731 	if (!(mask & TEST_BBDEV_VF_ITER_MAX))
732 		printf(
733 			"WARNING: iter_max was not specified in vector file and will be set to 0\n");
734 	if (!(mask & TEST_BBDEV_VF_EXPECTED_ITER_COUNT))
735 		printf(
736 			"WARNING: expected_iter_count was not specified in vector file and iter_count will not be validated\n");
737 	if (!(mask & TEST_BBDEV_VF_EXT_SCALE))
738 		printf(
739 			"WARNING: ext_scale was not specified in vector file and will be set to 0\n");
740 	if (!(mask & TEST_BBDEV_VF_OP_FLAGS)) {
741 		printf(
742 			"WARNING: op_flags was not specified in vector file and capabilities will not be validated\n");
743 		turbo_dec->num_maps = 0;
744 	} else if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_MAP_DEC) &&
745 			mask & TEST_BBDEV_VF_NUM_MAPS) {
746 		printf(
747 			"WARNING: RTE_BBDEV_TURBO_MAP_DEC was not set in vector file and num_maps will be set to 0\n");
748 		turbo_dec->num_maps = 0;
749 	}
750 	if (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))
751 		printf(
752 			"WARNING: expected_status was not specified in vector file and will be set to 0\n");
753 	return 0;
754 }
755 
756 /* checks encoder parameters */
757 static int
758 check_encoder(struct test_bbdev_vector *vector)
759 {
760 	unsigned char i;
761 	const int mask = vector->mask;
762 
763 	if (vector->entries[DATA_INPUT].nb_segments == 0)
764 		return -1;
765 
766 	for (i = 0; i < vector->entries[DATA_INPUT].nb_segments; i++)
767 		if (vector->entries[DATA_INPUT].segments[i].addr == NULL)
768 			return -1;
769 
770 	if (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0)
771 		return -1;
772 
773 	for (i = 0; i < vector->entries[DATA_HARD_OUTPUT].nb_segments; i++)
774 		if (vector->entries[DATA_HARD_OUTPUT].segments[i].addr == NULL)
775 			return -1;
776 
777 	if (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {
778 		printf(
779 			"WARNING: code_block_mode was not specified in vector file and will be set to 1\n");
780 		vector->turbo_enc.code_block_mode = 1;
781 	}
782 	if (vector->turbo_enc.code_block_mode == 0) {
783 		if (!(mask & TEST_BBDEV_VF_EA) && (vector->turbo_enc.op_flags &
784 				RTE_BBDEV_TURBO_RATE_MATCH))
785 			printf(
786 				"WARNING: ea was not specified in vector file and will be set to 0\n");
787 		if (!(mask & TEST_BBDEV_VF_EB) && (vector->turbo_enc.op_flags &
788 				RTE_BBDEV_TURBO_RATE_MATCH))
789 			printf(
790 				"WARNING: eb was not specified in vector file and will be set to 0\n");
791 		if (!(mask & TEST_BBDEV_VF_K_NEG))
792 			printf(
793 				"WARNING: k_neg was not specified in vector file and will be set to 0\n");
794 		if (!(mask & TEST_BBDEV_VF_K_POS))
795 			printf(
796 				"WARNING: k_pos was not specified in vector file and will be set to 0\n");
797 		if (!(mask & TEST_BBDEV_VF_C_NEG))
798 			printf(
799 				"WARNING: c_neg was not specified in vector file and will be set to 0\n");
800 		if (!(mask & TEST_BBDEV_VF_C)) {
801 			printf(
802 				"WARNING: c was not specified in vector file and will be set to 1\n");
803 			vector->turbo_enc.tb_params.c = 1;
804 		}
805 		if (!(mask & TEST_BBDEV_VF_CAB) && (vector->turbo_enc.op_flags &
806 				RTE_BBDEV_TURBO_RATE_MATCH))
807 			printf(
808 				"WARNING: cab was not specified in vector file and will be set to 0\n");
809 		if (!(mask & TEST_BBDEV_VF_NCB_NEG))
810 			printf(
811 				"WARNING: ncb_neg was not specified in vector file and will be set to 0\n");
812 		if (!(mask & TEST_BBDEV_VF_NCB_POS))
813 			printf(
814 				"WARNING: ncb_pos was not specified in vector file and will be set to 0\n");
815 		if (!(mask & TEST_BBDEV_VF_R))
816 			printf(
817 				"WARNING: r was not specified in vector file and will be set to 0\n");
818 	} else {
819 		if (!(mask & TEST_BBDEV_VF_E) && (vector->turbo_enc.op_flags &
820 				RTE_BBDEV_TURBO_RATE_MATCH))
821 			printf(
822 				"WARNING: e was not specified in vector file and will be set to 0\n");
823 		if (!(mask & TEST_BBDEV_VF_K))
824 			printf(
825 				"WARNING: k was not specified in vector file and will be set to 0\n");
826 		if (!(mask & TEST_BBDEV_VF_NCB))
827 			printf(
828 				"WARNING: ncb was not specified in vector file and will be set to 0\n");
829 	}
830 	if (!(mask & TEST_BBDEV_VF_RV_INDEX))
831 		printf(
832 			"WARNING: rv_index was not specified in vector file and will be set to 0\n");
833 	if (!(mask & TEST_BBDEV_VF_OP_FLAGS))
834 		printf(
835 			"WARNING: op_flags was not specified in vector file and capabilities will not be validated\n");
836 	if (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))
837 		printf(
838 			"WARNING: expected_status was not specified in vector file and will be set to 0\n");
839 
840 	return 0;
841 }
842 
843 static int
844 bbdev_check_vector(struct test_bbdev_vector *vector)
845 {
846 	if (vector->op_type == RTE_BBDEV_OP_TURBO_DEC) {
847 		if (check_decoder(vector) == -1)
848 			return -1;
849 	} else if (vector->op_type == RTE_BBDEV_OP_TURBO_ENC) {
850 		if (check_encoder(vector) == -1)
851 			return -1;
852 	} else if (vector->op_type != RTE_BBDEV_OP_NONE) {
853 		printf("Vector was not filled\n");
854 		return -1;
855 	}
856 
857 	return 0;
858 }
859 
860 int
861 test_bbdev_vector_read(const char *filename,
862 		struct test_bbdev_vector *vector)
863 {
864 	int ret = 0;
865 	size_t len = 0;
866 
867 	FILE *fp = NULL;
868 	char *line = NULL;
869 	char *entry = NULL;
870 
871 	fp = fopen(filename, "r");
872 	if (fp == NULL) {
873 		printf("File %s does not exist\n", filename);
874 		return -1;
875 	}
876 
877 	while (getline(&line, &len, fp) != -1) {
878 
879 		/* ignore comments and new lines */
880 		if (line[0] == '#' || line[0] == '/' || line[0] == '\n'
881 			|| line[0] == '\r')
882 			continue;
883 
884 		trim_space(line);
885 
886 		/* buffer for multiline */
887 		entry = realloc(entry, strlen(line) + 1);
888 		if (entry == NULL) {
889 			printf("Fail to realloc %zu bytes\n", strlen(line) + 1);
890 			ret = -ENOMEM;
891 			goto exit;
892 		}
893 
894 		strcpy(entry, line);
895 
896 		/* check if entry ends with , or = */
897 		if (entry[strlen(entry) - 1] == ','
898 			|| entry[strlen(entry) - 1] == '=') {
899 			while (getline(&line, &len, fp) != -1) {
900 				trim_space(line);
901 
902 				/* extend entry about length of new line */
903 				char *entry_extended = realloc(entry,
904 						strlen(line) +
905 						strlen(entry) + 1);
906 
907 				if (entry_extended == NULL) {
908 					printf("Fail to allocate %zu bytes\n",
909 							strlen(line) +
910 							strlen(entry) + 1);
911 					ret = -ENOMEM;
912 					goto exit;
913 				}
914 
915 				entry = entry_extended;
916 				/* entry has been allocated accordingly */
917 				strcpy(&entry[strlen(entry)], line);
918 
919 				if (entry[strlen(entry) - 1] != ',')
920 					break;
921 			}
922 		}
923 		ret = parse_entry(entry, vector);
924 		if (ret != 0) {
925 			printf("An error occurred while parsing!\n");
926 			goto exit;
927 		}
928 	}
929 	ret = bbdev_check_vector(vector);
930 	if (ret != 0)
931 		printf("An error occurred while checking!\n");
932 
933 exit:
934 	fclose(fp);
935 	free(line);
936 	free(entry);
937 
938 	return ret;
939 }
940