New upstream version 18.02
[deb_dpdk.git] / app / test-bbdev / test_bbdev_vector.c
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 }