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