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