xref: /dpdk/app/test-bbdev/test_bbdev_vector.c (revision cc360fd3)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4 
5 #ifdef RTE_EXEC_ENV_FREEBSD
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 	"harq_input",
22 	"harq_output",
23 };
24 
25 /* trim leading and trailing spaces */
26 static void
27 trim_space(char *str)
28 {
29 	char *start, *end;
30 
31 	for (start = str; *start; start++) {
32 		if (!isspace((unsigned char) start[0]))
33 			break;
34 	}
35 
36 	for (end = start + strlen(start); end > start + 1; end--) {
37 		if (!isspace((unsigned char) end[-1]))
38 			break;
39 	}
40 
41 	*end = 0;
42 
43 	/* Shift from "start" to the beginning of the string */
44 	if (start > str)
45 		memmove(str, start, (end - start) + 1);
46 }
47 
48 static bool
49 starts_with(const char *str, const char *pre)
50 {
51 	return strncmp(pre, str, strlen(pre)) == 0;
52 }
53 
54 /* tokenization test values separated by a comma */
55 static int
56 parse_values(char *tokens, uint32_t **data, uint32_t *data_length)
57 {
58 	uint32_t n_tokens = 0;
59 	uint32_t data_size = 32;
60 
61 	uint32_t *values, *values_resized;
62 	char *tok, *error = NULL;
63 
64 	tok = strtok(tokens, VALUE_DELIMITER);
65 	if (tok == NULL)
66 		return -1;
67 
68 	values = (uint32_t *)
69 			rte_zmalloc(NULL, sizeof(uint32_t) * data_size, 0);
70 	if (values == NULL)
71 		return -1;
72 
73 	while (tok != NULL) {
74 		values_resized = NULL;
75 
76 		if (n_tokens >= data_size) {
77 			data_size *= 2;
78 
79 			values_resized = (uint32_t *) rte_realloc(values,
80 				sizeof(uint32_t) * data_size, 0);
81 			if (values_resized == NULL) {
82 				rte_free(values);
83 				return -1;
84 			}
85 			values = values_resized;
86 		}
87 
88 		values[n_tokens] = (uint32_t) strtoul(tok, &error, 0);
89 
90 		if ((error == NULL) || (*error != '\0')) {
91 			printf("Failed with convert '%s'\n", tok);
92 			rte_free(values);
93 			return -1;
94 		}
95 
96 		*data_length = *data_length + (strlen(tok) - strlen("0x"))/2;
97 
98 		tok = strtok(NULL, VALUE_DELIMITER);
99 		if (tok == NULL)
100 			break;
101 
102 		n_tokens++;
103 	}
104 
105 	values_resized = (uint32_t *) rte_realloc(values,
106 		sizeof(uint32_t) * (n_tokens + 1), 0);
107 
108 	if (values_resized == NULL) {
109 		rte_free(values);
110 		return -1;
111 	}
112 
113 	*data = values_resized;
114 
115 	return 0;
116 }
117 
118 /* convert turbo decoder flag from string to unsigned long int*/
119 static int
120 op_decoder_flag_strtoul(char *token, uint32_t *op_flag_value)
121 {
122 	if (!strcmp(token, "RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE"))
123 		*op_flag_value = RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE;
124 	else if (!strcmp(token, "RTE_BBDEV_TURBO_CRC_TYPE_24B"))
125 		*op_flag_value = RTE_BBDEV_TURBO_CRC_TYPE_24B;
126 	else if (!strcmp(token, "RTE_BBDEV_TURBO_EQUALIZER"))
127 		*op_flag_value = RTE_BBDEV_TURBO_EQUALIZER;
128 	else if (!strcmp(token, "RTE_BBDEV_TURBO_SOFT_OUT_SATURATE"))
129 		*op_flag_value = RTE_BBDEV_TURBO_SOFT_OUT_SATURATE;
130 	else if (!strcmp(token, "RTE_BBDEV_TURBO_HALF_ITERATION_EVEN"))
131 		*op_flag_value = RTE_BBDEV_TURBO_HALF_ITERATION_EVEN;
132 	else if (!strcmp(token, "RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH"))
133 		*op_flag_value = RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH;
134 	else if (!strcmp(token, "RTE_BBDEV_TURBO_SOFT_OUTPUT"))
135 		*op_flag_value = RTE_BBDEV_TURBO_SOFT_OUTPUT;
136 	else if (!strcmp(token, "RTE_BBDEV_TURBO_EARLY_TERMINATION"))
137 		*op_flag_value = RTE_BBDEV_TURBO_EARLY_TERMINATION;
138 	else if (!strcmp(token, "RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN"))
139 		*op_flag_value = RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN;
140 	else if (!strcmp(token, "RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN"))
141 		*op_flag_value = RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN;
142 	else if (!strcmp(token, "RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT"))
143 		*op_flag_value = RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT;
144 	else if (!strcmp(token, "RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT"))
145 		*op_flag_value = RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT;
146 	else if (!strcmp(token, "RTE_BBDEV_TURBO_MAP_DEC"))
147 		*op_flag_value = RTE_BBDEV_TURBO_MAP_DEC;
148 	else if (!strcmp(token, "RTE_BBDEV_TURBO_DEC_SCATTER_GATHER"))
149 		*op_flag_value = RTE_BBDEV_TURBO_DEC_SCATTER_GATHER;
150 	else if (!strcmp(token, "RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP"))
151 		*op_flag_value = RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP;
152 	else {
153 		printf("The given value is not a turbo decoder flag\n");
154 		return -1;
155 	}
156 
157 	return 0;
158 }
159 
160 /* convert LDPC flag from string to unsigned long int*/
161 static int
162 op_ldpc_decoder_flag_strtoul(char *token, uint32_t *op_flag_value)
163 {
164 	if (!strcmp(token, "RTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK"))
165 		*op_flag_value = RTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK;
166 	else if (!strcmp(token, "RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK"))
167 		*op_flag_value = RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK;
168 	else if (!strcmp(token, "RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP"))
169 		*op_flag_value = RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP;
170 	else if (!strcmp(token, "RTE_BBDEV_LDPC_CRC_TYPE_16_CHECK"))
171 		*op_flag_value = RTE_BBDEV_LDPC_CRC_TYPE_16_CHECK;
172 	else if (!strcmp(token, "RTE_BBDEV_LDPC_DEINTERLEAVER_BYPASS"))
173 		*op_flag_value = RTE_BBDEV_LDPC_DEINTERLEAVER_BYPASS;
174 	else if (!strcmp(token, "RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE"))
175 		*op_flag_value = RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE;
176 	else if (!strcmp(token, "RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE"))
177 		*op_flag_value = RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE;
178 	else if (!strcmp(token, "RTE_BBDEV_LDPC_DECODE_BYPASS"))
179 		*op_flag_value = RTE_BBDEV_LDPC_DECODE_BYPASS;
180 	else if (!strcmp(token, "RTE_BBDEV_LDPC_SOFT_OUT_ENABLE"))
181 		*op_flag_value = RTE_BBDEV_LDPC_SOFT_OUT_ENABLE;
182 	else if (!strcmp(token, "RTE_BBDEV_LDPC_SOFT_OUT_RM_BYPASS"))
183 		*op_flag_value = RTE_BBDEV_LDPC_SOFT_OUT_RM_BYPASS;
184 	else if (!strcmp(token, "RTE_BBDEV_LDPC_SOFT_OUT_DEINTERLEAVER_BYPASS"))
185 		*op_flag_value = RTE_BBDEV_LDPC_SOFT_OUT_DEINTERLEAVER_BYPASS;
186 	else if (!strcmp(token, "RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE"))
187 		*op_flag_value = RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE;
188 	else if (!strcmp(token, "RTE_BBDEV_LDPC_DEC_INTERRUPTS"))
189 		*op_flag_value = RTE_BBDEV_LDPC_DEC_INTERRUPTS;
190 	else if (!strcmp(token, "RTE_BBDEV_LDPC_DEC_SCATTER_GATHER"))
191 		*op_flag_value = RTE_BBDEV_LDPC_DEC_SCATTER_GATHER;
192 	else if (!strcmp(token, "RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION"))
193 		*op_flag_value = RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION;
194 	else if (!strcmp(token, "RTE_BBDEV_LDPC_LLR_COMPRESSION"))
195 		*op_flag_value = RTE_BBDEV_LDPC_LLR_COMPRESSION;
196 	else if (!strcmp(token,
197 			"RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE"))
198 		*op_flag_value = RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE;
199 	else if (!strcmp(token,
200 			"RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE"))
201 		*op_flag_value = RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE;
202 	else if (!strcmp(token,
203 			"RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK"))
204 		*op_flag_value = RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK;
205 	else {
206 		printf("The given value is not a LDPC decoder flag\n");
207 		return -1;
208 	}
209 
210 	return 0;
211 }
212 
213 /* convert turbo encoder flag from string to unsigned long int*/
214 static int
215 op_encoder_flag_strtoul(char *token, uint32_t *op_flag_value)
216 {
217 	if (!strcmp(token, "RTE_BBDEV_TURBO_RV_INDEX_BYPASS"))
218 		*op_flag_value = RTE_BBDEV_TURBO_RV_INDEX_BYPASS;
219 	else if (!strcmp(token, "RTE_BBDEV_TURBO_RATE_MATCH"))
220 		*op_flag_value = RTE_BBDEV_TURBO_RATE_MATCH;
221 	else if (!strcmp(token, "RTE_BBDEV_TURBO_CRC_24B_ATTACH"))
222 		*op_flag_value = RTE_BBDEV_TURBO_CRC_24B_ATTACH;
223 	else if (!strcmp(token, "RTE_BBDEV_TURBO_CRC_24A_ATTACH"))
224 		*op_flag_value = RTE_BBDEV_TURBO_CRC_24A_ATTACH;
225 	else if (!strcmp(token, "RTE_BBDEV_TURBO_ENC_SCATTER_GATHER"))
226 		*op_flag_value = RTE_BBDEV_TURBO_ENC_SCATTER_GATHER;
227 	else {
228 		printf("The given value is not a turbo encoder flag\n");
229 		return -1;
230 	}
231 
232 	return 0;
233 }
234 
235 /* convert LDPC encoder flag from string to unsigned long int*/
236 static int
237 op_ldpc_encoder_flag_strtoul(char *token, uint32_t *op_flag_value)
238 {
239 	if (!strcmp(token, "RTE_BBDEV_LDPC_INTERLEAVER_BYPASS"))
240 		*op_flag_value = RTE_BBDEV_LDPC_INTERLEAVER_BYPASS;
241 	else if (!strcmp(token, "RTE_BBDEV_LDPC_RATE_MATCH"))
242 		*op_flag_value = RTE_BBDEV_LDPC_RATE_MATCH;
243 	else if (!strcmp(token, "RTE_BBDEV_LDPC_CRC_24A_ATTACH"))
244 		*op_flag_value = RTE_BBDEV_LDPC_CRC_24A_ATTACH;
245 	else if (!strcmp(token, "RTE_BBDEV_LDPC_CRC_24B_ATTACH"))
246 		*op_flag_value = RTE_BBDEV_LDPC_CRC_24B_ATTACH;
247 	else if (!strcmp(token, "RTE_BBDEV_LDPC_CRC_16_ATTACH"))
248 		*op_flag_value = RTE_BBDEV_LDPC_CRC_16_ATTACH;
249 	else if (!strcmp(token, "RTE_BBDEV_LDPC_ENC_INTERRUPTS"))
250 		*op_flag_value = RTE_BBDEV_LDPC_ENC_INTERRUPTS;
251 	else if (!strcmp(token, "RTE_BBDEV_LDPC_ENC_SCATTER_GATHER"))
252 		*op_flag_value = RTE_BBDEV_LDPC_ENC_SCATTER_GATHER;
253 	else {
254 		printf("The given value is not a turbo encoder flag\n");
255 		return -1;
256 	}
257 
258 	return 0;
259 }
260 
261 /* tokenization turbo decoder/encoder flags values separated by a comma */
262 static int
263 parse_turbo_flags(char *tokens, uint32_t *op_flags,
264 		enum rte_bbdev_op_type op_type)
265 {
266 	char *tok = NULL;
267 	uint32_t op_flag_value = 0;
268 
269 	tok = strtok(tokens, VALUE_DELIMITER);
270 	if (tok == NULL)
271 		return -1;
272 
273 	while (tok != NULL) {
274 		trim_space(tok);
275 		if (op_type == RTE_BBDEV_OP_TURBO_DEC) {
276 			if (op_decoder_flag_strtoul(tok, &op_flag_value) == -1)
277 				return -1;
278 		} else if (op_type == RTE_BBDEV_OP_TURBO_ENC) {
279 			if (op_encoder_flag_strtoul(tok, &op_flag_value) == -1)
280 				return -1;
281 		} else if (op_type == RTE_BBDEV_OP_LDPC_ENC) {
282 			if (op_ldpc_encoder_flag_strtoul(tok, &op_flag_value)
283 					== -1)
284 				return -1;
285 		} else if (op_type == RTE_BBDEV_OP_LDPC_DEC) {
286 			if (op_ldpc_decoder_flag_strtoul(tok, &op_flag_value)
287 					== -1)
288 				return -1;
289 		} else {
290 			return -1;
291 		}
292 
293 		*op_flags = *op_flags | op_flag_value;
294 
295 		tok = strtok(NULL, VALUE_DELIMITER);
296 		if (tok == NULL)
297 			break;
298 	}
299 
300 	return 0;
301 }
302 
303 /* convert turbo encoder/decoder op_type from string to enum*/
304 static int
305 op_turbo_type_strtol(char *token, enum rte_bbdev_op_type *op_type)
306 {
307 	trim_space(token);
308 	if (!strcmp(token, "RTE_BBDEV_OP_TURBO_DEC"))
309 		*op_type = RTE_BBDEV_OP_TURBO_DEC;
310 	else if (!strcmp(token, "RTE_BBDEV_OP_TURBO_ENC"))
311 		*op_type = RTE_BBDEV_OP_TURBO_ENC;
312 	else if (!strcmp(token, "RTE_BBDEV_OP_LDPC_ENC"))
313 		*op_type = RTE_BBDEV_OP_LDPC_ENC;
314 	else if (!strcmp(token, "RTE_BBDEV_OP_LDPC_DEC"))
315 		*op_type = RTE_BBDEV_OP_LDPC_DEC;
316 	else if (!strcmp(token, "RTE_BBDEV_OP_NONE"))
317 		*op_type = RTE_BBDEV_OP_NONE;
318 	else {
319 		printf("Not valid turbo op_type: '%s'\n", token);
320 		return -1;
321 	}
322 
323 	return 0;
324 }
325 
326 /* tokenization expected status values separated by a comma */
327 static int
328 parse_expected_status(char *tokens, int *status, enum rte_bbdev_op_type op_type)
329 {
330 	char *tok = NULL;
331 	bool status_ok = false;
332 
333 	tok = strtok(tokens, VALUE_DELIMITER);
334 	if (tok == NULL)
335 		return -1;
336 
337 	while (tok != NULL) {
338 		trim_space(tok);
339 		if (!strcmp(tok, "OK"))
340 			status_ok = true;
341 		else if (!strcmp(tok, "DMA"))
342 			*status = *status | (1 << RTE_BBDEV_DRV_ERROR);
343 		else if (!strcmp(tok, "FCW"))
344 			*status = *status | (1 << RTE_BBDEV_DATA_ERROR);
345 		else if (!strcmp(tok, "SYNCRC")) {
346 			*status = *status | (1 << RTE_BBDEV_SYNDROME_ERROR);
347 			*status = *status | (1 << RTE_BBDEV_CRC_ERROR);
348 		} else if (!strcmp(tok, "SYN"))
349 			*status = *status | (1 << RTE_BBDEV_SYNDROME_ERROR);
350 		else if (!strcmp(tok, "CRC")) {
351 			if ((op_type == RTE_BBDEV_OP_TURBO_DEC) ||
352 					(op_type == RTE_BBDEV_OP_LDPC_DEC))
353 				*status = *status | (1 << RTE_BBDEV_CRC_ERROR);
354 			else {
355 				printf(
356 						"CRC is only a valid value for decoder\n");
357 				return -1;
358 			}
359 		} else {
360 			printf("Not valid status: '%s'\n", tok);
361 			return -1;
362 		}
363 
364 		tok = strtok(NULL, VALUE_DELIMITER);
365 		if (tok == NULL)
366 			break;
367 	}
368 
369 	if (status_ok && *status != 0) {
370 		printf(
371 				"Not valid status values. Cannot be OK and ERROR at the same time.\n");
372 		return -1;
373 	}
374 
375 	return 0;
376 }
377 
378 /* parse ops data entry (there can be more than 1 input entry, each will be
379  * contained in a separate op_data_buf struct)
380  */
381 static int
382 parse_data_entry(const char *key_token, char *token,
383 		struct test_bbdev_vector *vector, enum op_data_type type,
384 		const char *prefix)
385 {
386 	int ret;
387 	uint32_t data_length = 0;
388 	uint32_t *data = NULL;
389 	unsigned int id;
390 	struct op_data_buf *op_data;
391 	unsigned int *nb_ops;
392 
393 	if (type >= DATA_NUM_TYPES) {
394 		printf("Unknown op type: %d!\n", type);
395 		return -1;
396 	}
397 
398 	op_data = vector->entries[type].segments;
399 	nb_ops = &vector->entries[type].nb_segments;
400 
401 	if (*nb_ops >= RTE_BBDEV_TURBO_MAX_CODE_BLOCKS) {
402 		printf("Too many segments (code blocks defined): %u, max %d!\n",
403 				*nb_ops, RTE_BBDEV_TURBO_MAX_CODE_BLOCKS);
404 		return -1;
405 	}
406 
407 	if (sscanf(key_token + strlen(prefix), "%u", &id) != 1) {
408 		printf("Missing ID of %s\n", prefix);
409 		return -1;
410 	}
411 	if (id != *nb_ops) {
412 		printf(
413 			"Please order data entries sequentially, i.e. %s0, %s1, ...\n",
414 				prefix, prefix);
415 		return -1;
416 	}
417 
418 	/* Clear new op data struct */
419 	memset(op_data + *nb_ops, 0, sizeof(struct op_data_buf));
420 
421 	ret = parse_values(token, &data, &data_length);
422 	if (!ret) {
423 		op_data[*nb_ops].addr = data;
424 		op_data[*nb_ops].length = data_length;
425 		++(*nb_ops);
426 	}
427 
428 	return ret;
429 }
430 
431 /* parses turbo decoder parameters and assigns to global variable */
432 static int
433 parse_decoder_params(const char *key_token, char *token,
434 		struct test_bbdev_vector *vector)
435 {
436 	int ret = 0, status = 0;
437 	uint32_t op_flags = 0;
438 	char *err = NULL;
439 
440 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
441 
442 	/* compare keys */
443 	if (starts_with(key_token, op_data_prefixes[DATA_INPUT]))
444 		ret = parse_data_entry(key_token, token, vector,
445 				DATA_INPUT, op_data_prefixes[DATA_INPUT]);
446 
447 	else if (starts_with(key_token, op_data_prefixes[DATA_SOFT_OUTPUT]))
448 		ret = parse_data_entry(key_token, token, vector,
449 				DATA_SOFT_OUTPUT,
450 				op_data_prefixes[DATA_SOFT_OUTPUT]);
451 
452 	else if (starts_with(key_token, op_data_prefixes[DATA_HARD_OUTPUT]))
453 		ret = parse_data_entry(key_token, token, vector,
454 				DATA_HARD_OUTPUT,
455 				op_data_prefixes[DATA_HARD_OUTPUT]);
456 	else if (!strcmp(key_token, "e")) {
457 		vector->mask |= TEST_BBDEV_VF_E;
458 		turbo_dec->cb_params.e = (uint32_t) strtoul(token, &err, 0);
459 	} else if (!strcmp(key_token, "ea")) {
460 		vector->mask |= TEST_BBDEV_VF_EA;
461 		turbo_dec->tb_params.ea = (uint32_t) strtoul(token, &err, 0);
462 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
463 	} else if (!strcmp(key_token, "eb")) {
464 		vector->mask |= TEST_BBDEV_VF_EB;
465 		turbo_dec->tb_params.eb = (uint32_t) strtoul(token, &err, 0);
466 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
467 	} else if (!strcmp(key_token, "k")) {
468 		vector->mask |= TEST_BBDEV_VF_K;
469 		turbo_dec->cb_params.k = (uint16_t) strtoul(token, &err, 0);
470 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
471 	} else if (!strcmp(key_token, "k_pos")) {
472 		vector->mask |= TEST_BBDEV_VF_K_POS;
473 		turbo_dec->tb_params.k_pos = (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_dec->tb_params.k_neg = (uint16_t) strtoul(token, &err, 0);
478 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
479 	} else if (!strcmp(key_token, "c")) {
480 		vector->mask |= TEST_BBDEV_VF_C;
481 		turbo_dec->tb_params.c = (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_dec->tb_params.c_neg = (uint16_t) strtoul(token, &err, 0);
486 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
487 	} else if (!strcmp(key_token, "cab")) {
488 		vector->mask |= TEST_BBDEV_VF_CAB;
489 		turbo_dec->tb_params.cab = (uint8_t) strtoul(token, &err, 0);
490 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
491 	} else if (!strcmp(key_token, "rv_index")) {
492 		vector->mask |= TEST_BBDEV_VF_RV_INDEX;
493 		turbo_dec->rv_index = (uint8_t) strtoul(token, &err, 0);
494 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
495 	} else if (!strcmp(key_token, "iter_max")) {
496 		vector->mask |= TEST_BBDEV_VF_ITER_MAX;
497 		turbo_dec->iter_max = (uint8_t) strtoul(token, &err, 0);
498 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
499 	} else if (!strcmp(key_token, "iter_min")) {
500 		vector->mask |= TEST_BBDEV_VF_ITER_MIN;
501 		turbo_dec->iter_min = (uint8_t) strtoul(token, &err, 0);
502 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
503 	} else if (!strcmp(key_token, "expected_iter_count")) {
504 		vector->mask |= TEST_BBDEV_VF_EXPECTED_ITER_COUNT;
505 		turbo_dec->iter_count = (uint8_t) strtoul(token, &err, 0);
506 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
507 	} else if (!strcmp(key_token, "ext_scale")) {
508 		vector->mask |= TEST_BBDEV_VF_EXT_SCALE;
509 		turbo_dec->ext_scale = (uint8_t) strtoul(token, &err, 0);
510 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
511 	} else if (!strcmp(key_token, "num_maps")) {
512 		vector->mask |= TEST_BBDEV_VF_NUM_MAPS;
513 		turbo_dec->num_maps = (uint8_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_dec->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_dec->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_dec->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 dec 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 /* parses turbo encoder parameters and assigns to global variable */
548 static int
549 parse_encoder_params(const char *key_token, char *token,
550 		struct test_bbdev_vector *vector)
551 {
552 	int ret = 0, status = 0;
553 	uint32_t op_flags = 0;
554 	char *err = NULL;
555 
556 
557 	struct rte_bbdev_op_turbo_enc *turbo_enc = &vector->turbo_enc;
558 
559 	if (starts_with(key_token, op_data_prefixes[DATA_INPUT]))
560 		ret = parse_data_entry(key_token, token, vector,
561 				DATA_INPUT, op_data_prefixes[DATA_INPUT]);
562 	else if (starts_with(key_token, "output"))
563 		ret = parse_data_entry(key_token, token, vector,
564 				DATA_HARD_OUTPUT, "output");
565 	else if (!strcmp(key_token, "e")) {
566 		vector->mask |= TEST_BBDEV_VF_E;
567 		turbo_enc->cb_params.e = (uint32_t) strtoul(token, &err, 0);
568 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
569 	} else if (!strcmp(key_token, "ea")) {
570 		vector->mask |= TEST_BBDEV_VF_EA;
571 		turbo_enc->tb_params.ea = (uint32_t) strtoul(token, &err, 0);
572 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
573 	} else if (!strcmp(key_token, "eb")) {
574 		vector->mask |= TEST_BBDEV_VF_EB;
575 		turbo_enc->tb_params.eb = (uint32_t) strtoul(token, &err, 0);
576 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
577 	} else if (!strcmp(key_token, "k")) {
578 		vector->mask |= TEST_BBDEV_VF_K;
579 		turbo_enc->cb_params.k = (uint16_t) strtoul(token, &err, 0);
580 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
581 	} else if (!strcmp(key_token, "k_neg")) {
582 		vector->mask |= TEST_BBDEV_VF_K_NEG;
583 		turbo_enc->tb_params.k_neg = (uint16_t) strtoul(token, &err, 0);
584 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
585 	} else if (!strcmp(key_token, "k_pos")) {
586 		vector->mask |= TEST_BBDEV_VF_K_POS;
587 		turbo_enc->tb_params.k_pos = (uint16_t) strtoul(token, &err, 0);
588 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
589 	} else if (!strcmp(key_token, "c_neg")) {
590 		vector->mask |= TEST_BBDEV_VF_C_NEG;
591 		turbo_enc->tb_params.c_neg = (uint8_t) strtoul(token, &err, 0);
592 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
593 	} else if (!strcmp(key_token, "c")) {
594 		vector->mask |= TEST_BBDEV_VF_C;
595 		turbo_enc->tb_params.c = (uint8_t) strtoul(token, &err, 0);
596 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
597 	} else if (!strcmp(key_token, "cab")) {
598 		vector->mask |= TEST_BBDEV_VF_CAB;
599 		turbo_enc->tb_params.cab = (uint8_t) strtoul(token, &err, 0);
600 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
601 	} else if (!strcmp(key_token, "rv_index")) {
602 		vector->mask |= TEST_BBDEV_VF_RV_INDEX;
603 		turbo_enc->rv_index = (uint8_t) strtoul(token, &err, 0);
604 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
605 	} else if (!strcmp(key_token, "ncb")) {
606 		vector->mask |= TEST_BBDEV_VF_NCB;
607 		turbo_enc->cb_params.ncb = (uint16_t) strtoul(token, &err, 0);
608 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
609 	} else if (!strcmp(key_token, "ncb_neg")) {
610 		vector->mask |= TEST_BBDEV_VF_NCB_NEG;
611 		turbo_enc->tb_params.ncb_neg =
612 				(uint16_t) strtoul(token, &err, 0);
613 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
614 	} else if (!strcmp(key_token, "ncb_pos")) {
615 		vector->mask |= TEST_BBDEV_VF_NCB_POS;
616 		turbo_enc->tb_params.ncb_pos =
617 				(uint16_t) strtoul(token, &err, 0);
618 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
619 	} else if (!strcmp(key_token, "r")) {
620 		vector->mask |= TEST_BBDEV_VF_R;
621 		turbo_enc->tb_params.r = (uint8_t) strtoul(token, &err, 0);
622 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
623 	} else if (!strcmp(key_token, "code_block_mode")) {
624 		vector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;
625 		turbo_enc->code_block_mode = (uint8_t) strtoul(token, &err, 0);
626 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
627 	} else if (!strcmp(key_token, "op_flags")) {
628 		vector->mask |= TEST_BBDEV_VF_OP_FLAGS;
629 		ret = parse_turbo_flags(token, &op_flags,
630 				vector->op_type);
631 		if (!ret)
632 			turbo_enc->op_flags = op_flags;
633 	} else if (!strcmp(key_token, "expected_status")) {
634 		vector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;
635 		ret = parse_expected_status(token, &status, vector->op_type);
636 		if (!ret)
637 			vector->expected_status = status;
638 	} else {
639 		printf("Not valid enc key: '%s'\n", key_token);
640 		return -1;
641 	}
642 
643 	if (ret != 0) {
644 		printf("Failed with convert '%s\t%s'\n", key_token, token);
645 		return -1;
646 	}
647 
648 	return 0;
649 }
650 
651 
652 /* parses LDPC encoder parameters and assigns to global variable */
653 static int
654 parse_ldpc_encoder_params(const char *key_token, char *token,
655 		struct test_bbdev_vector *vector)
656 {
657 	int ret = 0, status = 0;
658 	uint32_t op_flags = 0;
659 	char *err = NULL;
660 
661 	struct rte_bbdev_op_ldpc_enc *ldpc_enc = &vector->ldpc_enc;
662 
663 	if (starts_with(key_token, op_data_prefixes[DATA_INPUT]))
664 		ret = parse_data_entry(key_token, token, vector,
665 				DATA_INPUT,
666 				op_data_prefixes[DATA_INPUT]);
667 	else if (starts_with(key_token, "output"))
668 		ret = parse_data_entry(key_token, token, vector,
669 				DATA_HARD_OUTPUT,
670 				"output");
671 	else if (!strcmp(key_token, "e")) {
672 		vector->mask |= TEST_BBDEV_VF_E;
673 		ldpc_enc->cb_params.e = (uint32_t) strtoul(token, &err, 0);
674 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
675 	} else if (!strcmp(key_token, "ea")) {
676 		vector->mask |= TEST_BBDEV_VF_EA;
677 		ldpc_enc->tb_params.ea = (uint32_t) strtoul(token, &err, 0);
678 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
679 	} else if (!strcmp(key_token, "eb")) {
680 		vector->mask |= TEST_BBDEV_VF_EB;
681 		ldpc_enc->tb_params.eb = (uint32_t) strtoul(token, &err, 0);
682 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
683 	} else if (!strcmp(key_token, "c")) {
684 		vector->mask |= TEST_BBDEV_VF_C;
685 		ldpc_enc->tb_params.c = (uint8_t) strtoul(token, &err, 0);
686 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
687 	} else if (!strcmp(key_token, "cab")) {
688 		vector->mask |= TEST_BBDEV_VF_CAB;
689 		ldpc_enc->tb_params.cab = (uint8_t) strtoul(token, &err, 0);
690 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
691 	} else if (!strcmp(key_token, "rv_index")) {
692 		vector->mask |= TEST_BBDEV_VF_RV_INDEX;
693 		ldpc_enc->rv_index = (uint8_t) strtoul(token, &err, 0);
694 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
695 	} else if (!strcmp(key_token, "n_cb")) {
696 		vector->mask |= TEST_BBDEV_VF_NCB;
697 		ldpc_enc->n_cb = (uint16_t) strtoul(token, &err, 0);
698 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
699 	} else if (!strcmp(key_token, "r")) {
700 		vector->mask |= TEST_BBDEV_VF_R;
701 		ldpc_enc->tb_params.r = (uint8_t) strtoul(token, &err, 0);
702 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
703 	} else if (!strcmp(key_token, "q_m")) {
704 		vector->mask |= TEST_BBDEV_VF_QM;
705 		ldpc_enc->q_m = (uint8_t) strtoul(token, &err, 0);
706 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
707 	} else if (!strcmp(key_token, "basegraph")) {
708 		vector->mask |= TEST_BBDEV_VF_BG;
709 		ldpc_enc->basegraph = (uint8_t) strtoul(token, &err, 0);
710 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
711 	} else if (!strcmp(key_token, "z_c")) {
712 		vector->mask |= TEST_BBDEV_VF_ZC;
713 		ldpc_enc->z_c = (uint16_t) strtoul(token, &err, 0);
714 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
715 	} else if (!strcmp(key_token, "n_filler")) {
716 		vector->mask |= TEST_BBDEV_VF_F;
717 		ldpc_enc->n_filler = (uint16_t) strtoul(token, &err, 0);
718 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
719 	} else if (!strcmp(key_token, "code_block_mode")) {
720 		vector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;
721 		ldpc_enc->code_block_mode = (uint8_t) strtoul(token, &err, 0);
722 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
723 	} else if (!strcmp(key_token, "op_flags")) {
724 		vector->mask |= TEST_BBDEV_VF_OP_FLAGS;
725 		ret = parse_turbo_flags(token, &op_flags, vector->op_type);
726 		if (!ret)
727 			ldpc_enc->op_flags = op_flags;
728 	} else if (!strcmp(key_token, "expected_status")) {
729 		vector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;
730 		ret = parse_expected_status(token, &status, vector->op_type);
731 		if (!ret)
732 			vector->expected_status = status;
733 	} else {
734 		printf("Not valid ldpc enc key: '%s'\n", key_token);
735 		return -1;
736 	}
737 
738 	if (ret != 0) {
739 		printf("Failed with convert '%s\t%s'\n", key_token, token);
740 		return -1;
741 	}
742 
743 	return 0;
744 }
745 
746 /* parses LDPC decoder parameters and assigns to global variable */
747 static int
748 parse_ldpc_decoder_params(const char *key_token, char *token,
749 		struct test_bbdev_vector *vector)
750 {
751 	int ret = 0, status = 0;
752 	uint32_t op_flags = 0;
753 	char *err = NULL;
754 
755 	struct rte_bbdev_op_ldpc_dec *ldpc_dec = &vector->ldpc_dec;
756 
757 	if (starts_with(key_token, op_data_prefixes[DATA_INPUT]))
758 		ret = parse_data_entry(key_token, token, vector,
759 				DATA_INPUT,
760 				op_data_prefixes[DATA_INPUT]);
761 	else if (starts_with(key_token, "output"))
762 		ret = parse_data_entry(key_token, token, vector,
763 				DATA_HARD_OUTPUT,
764 				"output");
765 	else if (starts_with(key_token, op_data_prefixes[DATA_HARQ_INPUT]))
766 		ret = parse_data_entry(key_token, token, vector,
767 				DATA_HARQ_INPUT,
768 				op_data_prefixes[DATA_HARQ_INPUT]);
769 	else if (starts_with(key_token, op_data_prefixes[DATA_HARQ_OUTPUT]))
770 		ret = parse_data_entry(key_token, token, vector,
771 				DATA_HARQ_OUTPUT,
772 				op_data_prefixes[DATA_HARQ_OUTPUT]);
773 	else if (!strcmp(key_token, "e")) {
774 		vector->mask |= TEST_BBDEV_VF_E;
775 		ldpc_dec->cb_params.e = (uint32_t) strtoul(token, &err, 0);
776 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
777 	} else if (!strcmp(key_token, "ea")) {
778 		vector->mask |= TEST_BBDEV_VF_EA;
779 		ldpc_dec->tb_params.ea = (uint32_t) strtoul(token, &err, 0);
780 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
781 	} else if (!strcmp(key_token, "eb")) {
782 		vector->mask |= TEST_BBDEV_VF_EB;
783 		ldpc_dec->tb_params.eb = (uint32_t) strtoul(token, &err, 0);
784 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
785 	} else if (!strcmp(key_token, "c")) {
786 		vector->mask |= TEST_BBDEV_VF_C;
787 		ldpc_dec->tb_params.c = (uint8_t) strtoul(token, &err, 0);
788 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
789 	} else if (!strcmp(key_token, "cab")) {
790 		vector->mask |= TEST_BBDEV_VF_CAB;
791 		ldpc_dec->tb_params.cab = (uint8_t) strtoul(token, &err, 0);
792 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
793 	} else if (!strcmp(key_token, "rv_index")) {
794 		vector->mask |= TEST_BBDEV_VF_RV_INDEX;
795 		ldpc_dec->rv_index = (uint8_t) strtoul(token, &err, 0);
796 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
797 	} else if (!strcmp(key_token, "n_cb")) {
798 		vector->mask |= TEST_BBDEV_VF_NCB;
799 		ldpc_dec->n_cb = (uint16_t) strtoul(token, &err, 0);
800 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
801 	} else if (!strcmp(key_token, "r")) {
802 		vector->mask |= TEST_BBDEV_VF_R;
803 		ldpc_dec->tb_params.r = (uint8_t) strtoul(token, &err, 0);
804 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
805 	} else if (!strcmp(key_token, "q_m")) {
806 		vector->mask |= TEST_BBDEV_VF_QM;
807 		ldpc_dec->q_m = (uint8_t) strtoul(token, &err, 0);
808 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
809 	} else if (!strcmp(key_token, "basegraph")) {
810 		vector->mask |= TEST_BBDEV_VF_BG;
811 		ldpc_dec->basegraph = (uint8_t) strtoul(token, &err, 0);
812 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
813 	} else if (!strcmp(key_token, "z_c")) {
814 		vector->mask |= TEST_BBDEV_VF_ZC;
815 		ldpc_dec->z_c = (uint16_t) strtoul(token, &err, 0);
816 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
817 	} else if (!strcmp(key_token, "n_filler")) {
818 		vector->mask |= TEST_BBDEV_VF_F;
819 		ldpc_dec->n_filler = (uint16_t) strtoul(token, &err, 0);
820 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
821 	} else if (!strcmp(key_token, "expected_iter_count")) {
822 		vector->mask |= TEST_BBDEV_VF_EXPECTED_ITER_COUNT;
823 		ldpc_dec->iter_count = (uint8_t) strtoul(token, &err, 0);
824 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
825 	} else if (!strcmp(key_token, "iter_max")) {
826 		vector->mask |= TEST_BBDEV_VF_ITER_MAX;
827 		ldpc_dec->iter_max = (uint8_t) strtoul(token, &err, 0);
828 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
829 	} else if (!strcmp(key_token, "code_block_mode")) {
830 		vector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;
831 		ldpc_dec->code_block_mode = (uint8_t) strtoul(token, &err, 0);
832 		ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
833 	} else if (!strcmp(key_token, "op_flags")) {
834 		vector->mask |= TEST_BBDEV_VF_OP_FLAGS;
835 		ret = parse_turbo_flags(token, &op_flags, vector->op_type);
836 		if (!ret)
837 			ldpc_dec->op_flags = op_flags;
838 	} else if (!strcmp(key_token, "expected_status")) {
839 		vector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;
840 		ret = parse_expected_status(token, &status, vector->op_type);
841 		if (!ret)
842 			vector->expected_status = status;
843 	} else {
844 		printf("Not valid ldpc dec key: '%s'\n", key_token);
845 		return -1;
846 	}
847 
848 	if (ret != 0) {
849 		printf("Failed with convert '%s\t%s'\n", key_token, token);
850 		return -1;
851 	}
852 
853 	return 0;
854 }
855 
856 /* checks the type of key and assigns data */
857 static int
858 parse_entry(char *entry, struct test_bbdev_vector *vector)
859 {
860 	int ret = 0;
861 	char *token, *key_token;
862 	enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_NONE;
863 
864 	if (entry == NULL) {
865 		printf("Expected entry value\n");
866 		return -1;
867 	}
868 
869 	/* get key */
870 	token = strtok(entry, ENTRY_DELIMITER);
871 	key_token = token;
872 	/* get values for key */
873 	token = strtok(NULL, ENTRY_DELIMITER);
874 
875 	if (key_token == NULL || token == NULL) {
876 		printf("Expected 'key = values' but was '%.40s'..\n", entry);
877 		return -1;
878 	}
879 	trim_space(key_token);
880 
881 	/* first key_token has to specify type of operation */
882 	if (vector->op_type == RTE_BBDEV_OP_NONE) {
883 		if (!strcmp(key_token, "op_type")) {
884 			ret = op_turbo_type_strtol(token, &op_type);
885 			if (!ret)
886 				vector->op_type = op_type;
887 			return (!ret) ? 0 : -1;
888 		}
889 		printf("First key_token (%s) does not specify op_type\n",
890 				key_token);
891 		return -1;
892 	}
893 
894 	/* compare keys */
895 	if (vector->op_type == RTE_BBDEV_OP_TURBO_DEC) {
896 		if (parse_decoder_params(key_token, token, vector) == -1)
897 			return -1;
898 	} else if (vector->op_type == RTE_BBDEV_OP_TURBO_ENC) {
899 		if (parse_encoder_params(key_token, token, vector) == -1)
900 			return -1;
901 	} else if (vector->op_type == RTE_BBDEV_OP_LDPC_ENC) {
902 		if (parse_ldpc_encoder_params(key_token, token, vector) == -1)
903 			return -1;
904 	} else if (vector->op_type == RTE_BBDEV_OP_LDPC_DEC) {
905 		if (parse_ldpc_decoder_params(key_token, token, vector) == -1)
906 			return -1;
907 	}
908 
909 	return 0;
910 }
911 
912 static int
913 check_decoder_segments(struct test_bbdev_vector *vector)
914 {
915 	unsigned char i;
916 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
917 
918 	if (vector->entries[DATA_INPUT].nb_segments == 0)
919 		return -1;
920 
921 	for (i = 0; i < vector->entries[DATA_INPUT].nb_segments; i++)
922 		if (vector->entries[DATA_INPUT].segments[i].addr == NULL)
923 			return -1;
924 
925 	if (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0)
926 		return -1;
927 
928 	for (i = 0; i < vector->entries[DATA_HARD_OUTPUT].nb_segments;
929 			i++)
930 		if (vector->entries[DATA_HARD_OUTPUT].segments[i].addr == NULL)
931 			return -1;
932 
933 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_SOFT_OUTPUT) &&
934 			(vector->entries[DATA_SOFT_OUTPUT].nb_segments == 0))
935 		return -1;
936 
937 	for (i = 0; i < vector->entries[DATA_SOFT_OUTPUT].nb_segments;
938 			i++)
939 		if (vector->entries[DATA_SOFT_OUTPUT].segments[i].addr == NULL)
940 			return -1;
941 
942 	return 0;
943 }
944 
945 static int
946 check_ldpc_decoder_segments(struct test_bbdev_vector *vector)
947 {
948 	unsigned char i;
949 	struct rte_bbdev_op_ldpc_dec *ldpc_dec = &vector->ldpc_dec;
950 
951 	for (i = 0; i < vector->entries[DATA_INPUT].nb_segments; i++)
952 		if (vector->entries[DATA_INPUT].segments[i].addr == NULL)
953 			return -1;
954 
955 	for (i = 0; i < vector->entries[DATA_HARD_OUTPUT].nb_segments; i++)
956 		if (vector->entries[DATA_HARD_OUTPUT].segments[i].addr == NULL)
957 			return -1;
958 
959 	if ((ldpc_dec->op_flags & RTE_BBDEV_LDPC_SOFT_OUT_ENABLE) &&
960 			(vector->entries[DATA_SOFT_OUTPUT].nb_segments == 0))
961 		return -1;
962 
963 	for (i = 0; i < vector->entries[DATA_SOFT_OUTPUT].nb_segments; i++)
964 		if (vector->entries[DATA_SOFT_OUTPUT].segments[i].addr == NULL)
965 			return -1;
966 
967 	if ((ldpc_dec->op_flags & RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE) &&
968 			(vector->entries[DATA_HARQ_OUTPUT].nb_segments == 0))
969 		return -1;
970 
971 	for (i = 0; i < vector->entries[DATA_HARQ_OUTPUT].nb_segments; i++)
972 		if (vector->entries[DATA_HARQ_OUTPUT].segments[i].addr == NULL)
973 			return -1;
974 
975 	return 0;
976 }
977 
978 static int
979 check_decoder_llr_spec(struct test_bbdev_vector *vector)
980 {
981 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
982 
983 	/* Check input LLR sign formalism specification */
984 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN) &&
985 			(turbo_dec->op_flags &
986 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN)) {
987 		printf(
988 			"Both positive and negative LLR input flags were set!\n");
989 		return -1;
990 	}
991 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN) &&
992 			!(turbo_dec->op_flags &
993 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN)) {
994 		printf(
995 			"INFO: input LLR sign formalism was not specified and will be set to negative LLR for '1' bit\n");
996 		turbo_dec->op_flags |= RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN;
997 	}
998 
999 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_SOFT_OUTPUT))
1000 		return 0;
1001 
1002 	/* Check output LLR sign formalism specification */
1003 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT) &&
1004 			(turbo_dec->op_flags &
1005 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT)) {
1006 		printf(
1007 			"Both positive and negative LLR output flags were set!\n");
1008 		return -1;
1009 	}
1010 	if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT) &&
1011 			!(turbo_dec->op_flags &
1012 			RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT)) {
1013 		printf(
1014 			"INFO: soft output LLR sign formalism was not specified and will be set to negative LLR for '1' bit\n");
1015 		turbo_dec->op_flags |=
1016 				RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT;
1017 	}
1018 
1019 	return 0;
1020 }
1021 
1022 static int
1023 check_decoder_op_flags(struct test_bbdev_vector *vector)
1024 {
1025 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
1026 
1027 	if ((turbo_dec->op_flags & RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP) &&
1028 		!(turbo_dec->op_flags & RTE_BBDEV_TURBO_CRC_TYPE_24B)) {
1029 		printf(
1030 			"WARNING: RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP flag is missing RTE_BBDEV_TURBO_CRC_TYPE_24B\n");
1031 		return -1;
1032 	}
1033 
1034 	return 0;
1035 }
1036 
1037 /* checks decoder parameters */
1038 static int
1039 check_decoder(struct test_bbdev_vector *vector)
1040 {
1041 	struct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;
1042 	const int mask = vector->mask;
1043 
1044 	if (check_decoder_segments(vector) < 0)
1045 		return -1;
1046 
1047 	if (check_decoder_llr_spec(vector) < 0)
1048 		return -1;
1049 
1050 	if (check_decoder_op_flags(vector) < 0)
1051 		return -1;
1052 
1053 	/* Check which params were set */
1054 	if (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {
1055 		printf(
1056 			"WARNING: code_block_mode was not specified in vector file and will be set to 1 (0 - TB Mode, 1 - CB mode)\n");
1057 		turbo_dec->code_block_mode = RTE_BBDEV_CODE_BLOCK;
1058 	}
1059 	if (turbo_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
1060 		if (!(mask & TEST_BBDEV_VF_EA))
1061 			printf(
1062 				"WARNING: ea was not specified in vector file and will be set to 0\n");
1063 		if (!(mask & TEST_BBDEV_VF_EB))
1064 			printf(
1065 				"WARNING: eb was not specified in vector file and will be set to 0\n");
1066 		if (!(mask & TEST_BBDEV_VF_K_NEG))
1067 			printf(
1068 				"WARNING: k_neg was not specified in vector file and will be set to 0\n");
1069 		if (!(mask & TEST_BBDEV_VF_K_POS))
1070 			printf(
1071 				"WARNING: k_pos was not specified in vector file and will be set to 0\n");
1072 		if (!(mask & TEST_BBDEV_VF_C_NEG))
1073 			printf(
1074 				"WARNING: c_neg was not specified in vector file and will be set to 0\n");
1075 		if (!(mask & TEST_BBDEV_VF_C)) {
1076 			printf(
1077 				"WARNING: c was not specified in vector file and will be set to 1\n");
1078 			turbo_dec->tb_params.c = 1;
1079 		}
1080 		if (!(mask & TEST_BBDEV_VF_CAB))
1081 			printf(
1082 				"WARNING: cab was not specified in vector file and will be set to 0\n");
1083 		if (!(mask & TEST_BBDEV_VF_R))
1084 			printf(
1085 				"WARNING: r was not specified in vector file and will be set to 0\n");
1086 	} else {
1087 		if (!(mask & TEST_BBDEV_VF_E))
1088 			printf(
1089 				"WARNING: e was not specified in vector file and will be set to 0\n");
1090 		if (!(mask & TEST_BBDEV_VF_K))
1091 			printf(
1092 				"WARNING: k was not specified in vector file and will be set to 0\n");
1093 	}
1094 	if (!(mask & TEST_BBDEV_VF_RV_INDEX))
1095 		printf(
1096 			"INFO: rv_index was not specified in vector file and will be set to 0\n");
1097 	if (!(mask & TEST_BBDEV_VF_ITER_MIN))
1098 		printf(
1099 			"WARNING: iter_min was not specified in vector file and will be set to 0\n");
1100 	if (!(mask & TEST_BBDEV_VF_ITER_MAX))
1101 		printf(
1102 			"WARNING: iter_max was not specified in vector file and will be set to 0\n");
1103 	if (!(mask & TEST_BBDEV_VF_EXPECTED_ITER_COUNT))
1104 		printf(
1105 			"WARNING: expected_iter_count was not specified in vector file and iter_count will not be validated\n");
1106 	if (!(mask & TEST_BBDEV_VF_EXT_SCALE))
1107 		printf(
1108 			"WARNING: ext_scale was not specified in vector file and will be set to 0\n");
1109 	if (!(mask & TEST_BBDEV_VF_OP_FLAGS)) {
1110 		printf(
1111 			"WARNING: op_flags was not specified in vector file and capabilities will not be validated\n");
1112 		turbo_dec->num_maps = 0;
1113 	} else if (!(turbo_dec->op_flags & RTE_BBDEV_TURBO_MAP_DEC) &&
1114 			mask & TEST_BBDEV_VF_NUM_MAPS) {
1115 		printf(
1116 			"INFO: RTE_BBDEV_TURBO_MAP_DEC was not set in vector file and num_maps will be set to 0\n");
1117 		turbo_dec->num_maps = 0;
1118 	}
1119 	if (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))
1120 		printf(
1121 			"WARNING: expected_status was not specified in vector file and will be set to 0\n");
1122 	return 0;
1123 }
1124 
1125 /* checks LDPC decoder parameters */
1126 static int
1127 check_ldpc_decoder(struct test_bbdev_vector *vector)
1128 {
1129 	struct rte_bbdev_op_ldpc_dec *ldpc_dec = &vector->ldpc_dec;
1130 	const int mask = vector->mask;
1131 
1132 	if (check_ldpc_decoder_segments(vector) < 0)
1133 		return -1;
1134 
1135 	/*
1136 	 * if (check_ldpc_decoder_llr_spec(vector) < 0)
1137 	 *	return -1;
1138 	 *
1139 	 * if (check_ldpc_decoder_op_flags(vector) < 0)
1140 	 *	return -1;
1141 	 */
1142 
1143 	/* Check which params were set */
1144 	if (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {
1145 		printf(
1146 			"WARNING: code_block_mode was not specified in vector file and will be set to 1 (0 - TB Mode, 1 - CB mode)\n");
1147 		ldpc_dec->code_block_mode = RTE_BBDEV_CODE_BLOCK;
1148 	}
1149 	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
1150 		if (!(mask & TEST_BBDEV_VF_EA))
1151 			printf(
1152 				"WARNING: ea was not specified in vector file and will be set to 0\n");
1153 		if (!(mask & TEST_BBDEV_VF_EB))
1154 			printf(
1155 				"WARNING: eb was not specified in vector file and will be set to 0\n");
1156 		if (!(mask & TEST_BBDEV_VF_C)) {
1157 			printf(
1158 				"WARNING: c was not specified in vector file and will be set to 1\n");
1159 			ldpc_dec->tb_params.c = 1;
1160 		}
1161 		if (!(mask & TEST_BBDEV_VF_CAB))
1162 			printf(
1163 				"WARNING: cab was not specified in vector file and will be set to 0\n");
1164 		if (!(mask & TEST_BBDEV_VF_R))
1165 			printf(
1166 				"WARNING: r was not specified in vector file and will be set to 0\n");
1167 	} else {
1168 		if (!(mask & TEST_BBDEV_VF_E))
1169 			printf(
1170 				"WARNING: e was not specified in vector file and will be set to 0\n");
1171 	}
1172 	if (!(mask & TEST_BBDEV_VF_RV_INDEX))
1173 		printf(
1174 			"INFO: rv_index was not specified in vector file and will be set to 0\n");
1175 	if (!(mask & TEST_BBDEV_VF_ITER_MAX))
1176 		printf(
1177 			"WARNING: iter_max was not specified in vector file and will be set to 0\n");
1178 	if (!(mask & TEST_BBDEV_VF_EXPECTED_ITER_COUNT))
1179 		printf(
1180 			"WARNING: expected_iter_count was not specified in vector file and iter_count will not be validated\n");
1181 	if (!(mask & TEST_BBDEV_VF_OP_FLAGS)) {
1182 		printf(
1183 			"WARNING: op_flags was not specified in vector file and capabilities will not be validated\n");
1184 	}
1185 	if (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))
1186 		printf(
1187 			"WARNING: expected_status was not specified in vector file and will be set to 0\n");
1188 	return 0;
1189 }
1190 
1191 /* checks encoder parameters */
1192 static int
1193 check_encoder(struct test_bbdev_vector *vector)
1194 {
1195 	unsigned char i;
1196 	const int mask = vector->mask;
1197 
1198 	if (vector->entries[DATA_INPUT].nb_segments == 0)
1199 		return -1;
1200 
1201 	for (i = 0; i < vector->entries[DATA_INPUT].nb_segments; i++)
1202 		if (vector->entries[DATA_INPUT].segments[i].addr == NULL)
1203 			return -1;
1204 
1205 	if (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0)
1206 		return -1;
1207 
1208 	for (i = 0; i < vector->entries[DATA_HARD_OUTPUT].nb_segments; i++)
1209 		if (vector->entries[DATA_HARD_OUTPUT].segments[i].addr == NULL)
1210 			return -1;
1211 
1212 	if (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {
1213 		printf(
1214 			"WARNING: code_block_mode was not specified in vector file and will be set to 1\n");
1215 		vector->turbo_enc.code_block_mode = RTE_BBDEV_CODE_BLOCK;
1216 	}
1217 	if (vector->turbo_enc.code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
1218 		if (!(mask & TEST_BBDEV_VF_EA) && (vector->turbo_enc.op_flags &
1219 				RTE_BBDEV_TURBO_RATE_MATCH))
1220 			printf(
1221 				"WARNING: ea was not specified in vector file and will be set to 0\n");
1222 		if (!(mask & TEST_BBDEV_VF_EB) && (vector->turbo_enc.op_flags &
1223 				RTE_BBDEV_TURBO_RATE_MATCH))
1224 			printf(
1225 				"WARNING: eb was not specified in vector file and will be set to 0\n");
1226 		if (!(mask & TEST_BBDEV_VF_K_NEG))
1227 			printf(
1228 				"WARNING: k_neg was not specified in vector file and will be set to 0\n");
1229 		if (!(mask & TEST_BBDEV_VF_K_POS))
1230 			printf(
1231 				"WARNING: k_pos was not specified in vector file and will be set to 0\n");
1232 		if (!(mask & TEST_BBDEV_VF_C_NEG))
1233 			printf(
1234 				"WARNING: c_neg was not specified in vector file and will be set to 0\n");
1235 		if (!(mask & TEST_BBDEV_VF_C)) {
1236 			printf(
1237 				"WARNING: c was not specified in vector file and will be set to 1\n");
1238 			vector->turbo_enc.tb_params.c = 1;
1239 		}
1240 		if (!(mask & TEST_BBDEV_VF_CAB) && (vector->turbo_enc.op_flags &
1241 				RTE_BBDEV_TURBO_RATE_MATCH))
1242 			printf(
1243 				"WARNING: cab was not specified in vector file and will be set to 0\n");
1244 		if (!(mask & TEST_BBDEV_VF_NCB_NEG))
1245 			printf(
1246 				"WARNING: ncb_neg was not specified in vector file and will be set to 0\n");
1247 		if (!(mask & TEST_BBDEV_VF_NCB_POS))
1248 			printf(
1249 				"WARNING: ncb_pos was not specified in vector file and will be set to 0\n");
1250 		if (!(mask & TEST_BBDEV_VF_R))
1251 			printf(
1252 				"WARNING: r was not specified in vector file and will be set to 0\n");
1253 	} else {
1254 		if (!(mask & TEST_BBDEV_VF_E) && (vector->turbo_enc.op_flags &
1255 				RTE_BBDEV_TURBO_RATE_MATCH))
1256 			printf(
1257 				"WARNING: e was not specified in vector file and will be set to 0\n");
1258 		if (!(mask & TEST_BBDEV_VF_K))
1259 			printf(
1260 				"WARNING: k was not specified in vector file and will be set to 0\n");
1261 		if (!(mask & TEST_BBDEV_VF_NCB))
1262 			printf(
1263 				"WARNING: ncb was not specified in vector file and will be set to 0\n");
1264 	}
1265 	if (!(mask & TEST_BBDEV_VF_RV_INDEX))
1266 		printf(
1267 			"INFO: rv_index was not specified in vector file and will be set to 0\n");
1268 	if (!(mask & TEST_BBDEV_VF_OP_FLAGS))
1269 		printf(
1270 			"INFO: op_flags was not specified in vector file and capabilities will not be validated\n");
1271 	if (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))
1272 		printf(
1273 			"WARNING: expected_status was not specified in vector file and will be set to 0\n");
1274 
1275 	return 0;
1276 }
1277 
1278 
1279 /* checks encoder parameters */
1280 static int
1281 check_ldpc_encoder(struct test_bbdev_vector *vector)
1282 {
1283 	unsigned char i;
1284 	const int mask = vector->mask;
1285 
1286 	if (vector->entries[DATA_INPUT].nb_segments == 0)
1287 		return -1;
1288 
1289 	for (i = 0; i < vector->entries[DATA_INPUT].nb_segments; i++)
1290 		if (vector->entries[DATA_INPUT].segments[i].addr == NULL)
1291 			return -1;
1292 
1293 	if (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0)
1294 		return -1;
1295 
1296 	for (i = 0; i < vector->entries[DATA_HARD_OUTPUT].nb_segments; i++)
1297 		if (vector->entries[DATA_HARD_OUTPUT].segments[i].addr == NULL)
1298 			return -1;
1299 
1300 	if (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {
1301 		printf(
1302 			"WARNING: code_block_mode was not specified in vector file and will be set to 1\n");
1303 		vector->turbo_enc.code_block_mode = RTE_BBDEV_CODE_BLOCK;
1304 	}
1305 	if (vector->turbo_enc.code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
1306 	} else {
1307 		if (!(mask & TEST_BBDEV_VF_E) && (vector->turbo_enc.op_flags &
1308 				RTE_BBDEV_TURBO_RATE_MATCH))
1309 			printf(
1310 				"WARNING: e was not specified in vector file and will be set to 0\n");
1311 		if (!(mask & TEST_BBDEV_VF_NCB))
1312 			printf(
1313 				"WARNING: ncb was not specified in vector file and will be set to 0\n");
1314 	}
1315 	if (!(mask & TEST_BBDEV_VF_BG))
1316 		printf(
1317 			"WARNING: BG was not specified in vector file and will be set to 0\n");
1318 	if (!(mask & TEST_BBDEV_VF_ZC))
1319 		printf(
1320 			"WARNING: Zc was not specified in vector file and will be set to 0\n");
1321 	if (!(mask & TEST_BBDEV_VF_RV_INDEX))
1322 		printf(
1323 			"INFO: rv_index was not specified in vector file and will be set to 0\n");
1324 	if (!(mask & TEST_BBDEV_VF_OP_FLAGS))
1325 		printf(
1326 			"INFO: op_flags was not specified in vector file and capabilities will not be validated\n");
1327 	if (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))
1328 		printf(
1329 			"WARNING: expected_status was not specified in vector file and will be set to 0\n");
1330 
1331 	return 0;
1332 }
1333 
1334 static int
1335 bbdev_check_vector(struct test_bbdev_vector *vector)
1336 {
1337 	if (vector->op_type == RTE_BBDEV_OP_TURBO_DEC) {
1338 		if (check_decoder(vector) == -1)
1339 			return -1;
1340 	} else if (vector->op_type == RTE_BBDEV_OP_TURBO_ENC) {
1341 		if (check_encoder(vector) == -1)
1342 			return -1;
1343 	} else if (vector->op_type == RTE_BBDEV_OP_LDPC_ENC) {
1344 		if (check_ldpc_encoder(vector) == -1)
1345 			return -1;
1346 	} else if (vector->op_type == RTE_BBDEV_OP_LDPC_DEC) {
1347 		if (check_ldpc_decoder(vector) == -1)
1348 			return -1;
1349 	} else if (vector->op_type != RTE_BBDEV_OP_NONE) {
1350 		printf("Vector was not filled\n");
1351 		return -1;
1352 	}
1353 
1354 	return 0;
1355 }
1356 
1357 int
1358 test_bbdev_vector_read(const char *filename,
1359 		struct test_bbdev_vector *vector)
1360 {
1361 	int ret = 0;
1362 	size_t len = 0;
1363 
1364 	FILE *fp = NULL;
1365 	char *line = NULL;
1366 	char *entry = NULL;
1367 
1368 	fp = fopen(filename, "r");
1369 	if (fp == NULL) {
1370 		printf("File %s does not exist\n", filename);
1371 		return -1;
1372 	}
1373 
1374 	while (getline(&line, &len, fp) != -1) {
1375 
1376 		/* ignore comments and new lines */
1377 		if (line[0] == '#' || line[0] == '/' || line[0] == '\n'
1378 			|| line[0] == '\r')
1379 			continue;
1380 
1381 		trim_space(line);
1382 
1383 		/* buffer for multiline */
1384 		entry = realloc(entry, strlen(line) + 1);
1385 		if (entry == NULL) {
1386 			printf("Fail to realloc %zu bytes\n", strlen(line) + 1);
1387 			ret = -ENOMEM;
1388 			goto exit;
1389 		}
1390 
1391 		strcpy(entry, line);
1392 
1393 		/* check if entry ends with , or = */
1394 		if (entry[strlen(entry) - 1] == ','
1395 			|| entry[strlen(entry) - 1] == '=') {
1396 			while (getline(&line, &len, fp) != -1) {
1397 				trim_space(line);
1398 
1399 				/* extend entry about length of new line */
1400 				char *entry_extended = realloc(entry,
1401 						strlen(line) +
1402 						strlen(entry) + 1);
1403 
1404 				if (entry_extended == NULL) {
1405 					printf("Fail to allocate %zu bytes\n",
1406 							strlen(line) +
1407 							strlen(entry) + 1);
1408 					ret = -ENOMEM;
1409 					goto exit;
1410 				}
1411 
1412 				entry = entry_extended;
1413 				/* entry has been allocated accordingly */
1414 				strcpy(&entry[strlen(entry)], line);
1415 
1416 				if (entry[strlen(entry) - 1] != ',')
1417 					break;
1418 			}
1419 		}
1420 		ret = parse_entry(entry, vector);
1421 		if (ret != 0) {
1422 			printf("An error occurred while parsing!\n");
1423 			goto exit;
1424 		}
1425 	}
1426 	ret = bbdev_check_vector(vector);
1427 	if (ret != 0)
1428 		printf("An error occurred while checking!\n");
1429 
1430 exit:
1431 	fclose(fp);
1432 	free(line);
1433 	free(entry);
1434 
1435 	return ret;
1436 }
1437