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 } 947