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