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