1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2020 Marvell International Ltd. 3 */ 4 #include <rte_bitmap.h> 5 #include <rte_ethdev.h> 6 #include <rte_eventdev.h> 7 #include <rte_event_eth_rx_adapter.h> 8 #include <rte_event_eth_tx_adapter.h> 9 #include <rte_malloc.h> 10 #include <stdbool.h> 11 12 #include "event_helper.h" 13 #include "ipsec-secgw.h" 14 15 #define DEFAULT_VECTOR_SIZE 16 16 #define DEFAULT_VECTOR_TMO 102400 17 18 static volatile bool eth_core_running; 19 20 static int 21 eh_get_enabled_cores(struct rte_bitmap *eth_core_mask) 22 { 23 int i, count = 0; 24 25 RTE_LCORE_FOREACH(i) { 26 /* Check if this core is enabled in core mask*/ 27 if (rte_bitmap_get(eth_core_mask, i)) { 28 /* Found enabled core */ 29 count++; 30 } 31 } 32 return count; 33 } 34 35 static inline unsigned int 36 eh_get_next_eth_core(struct eventmode_conf *em_conf) 37 { 38 static unsigned int prev_core = -1; 39 unsigned int next_core; 40 41 /* 42 * Make sure we have at least one eth core running, else the following 43 * logic would lead to an infinite loop. 44 */ 45 if (eh_get_enabled_cores(em_conf->eth_core_mask) == 0) { 46 EH_LOG_ERR("No enabled eth core found"); 47 return RTE_MAX_LCORE; 48 } 49 50 /* Only some cores are marked as eth cores, skip others */ 51 do { 52 /* Get the next core */ 53 next_core = rte_get_next_lcore(prev_core, 0, 1); 54 55 /* Check if we have reached max lcores */ 56 if (next_core == RTE_MAX_LCORE) 57 return next_core; 58 59 /* Update prev_core */ 60 prev_core = next_core; 61 } while (!(rte_bitmap_get(em_conf->eth_core_mask, next_core))); 62 63 return next_core; 64 } 65 66 static inline unsigned int 67 eh_get_next_active_core(struct eventmode_conf *em_conf, unsigned int prev_core) 68 { 69 unsigned int next_core; 70 71 /* Get next active core skipping cores reserved as eth cores */ 72 do { 73 /* Get the next core */ 74 next_core = rte_get_next_lcore(prev_core, 0, 0); 75 76 /* Check if we have reached max lcores */ 77 if (next_core == RTE_MAX_LCORE) 78 return next_core; 79 80 prev_core = next_core; 81 } while (rte_bitmap_get(em_conf->eth_core_mask, next_core)); 82 83 return next_core; 84 } 85 86 static struct eventdev_params * 87 eh_get_eventdev_params(struct eventmode_conf *em_conf, uint8_t eventdev_id) 88 { 89 int i; 90 91 for (i = 0; i < em_conf->nb_eventdev; i++) { 92 if (em_conf->eventdev_config[i].eventdev_id == eventdev_id) 93 break; 94 } 95 96 /* No match */ 97 if (i == em_conf->nb_eventdev) 98 return NULL; 99 100 return &(em_conf->eventdev_config[i]); 101 } 102 103 static inline bool 104 eh_dev_has_rx_internal_port(uint8_t eventdev_id) 105 { 106 bool flag = true; 107 int j, ret; 108 109 RTE_ETH_FOREACH_DEV(j) { 110 uint32_t caps = 0; 111 112 ret = rte_event_eth_rx_adapter_caps_get(eventdev_id, j, &caps); 113 if (ret < 0) 114 return false; 115 116 if (!(caps & RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT)) 117 flag = false; 118 } 119 return flag; 120 } 121 122 static inline bool 123 eh_dev_has_tx_internal_port(uint8_t eventdev_id) 124 { 125 bool flag = true; 126 int j, ret; 127 128 RTE_ETH_FOREACH_DEV(j) { 129 uint32_t caps = 0; 130 131 ret = rte_event_eth_tx_adapter_caps_get(eventdev_id, j, &caps); 132 if (ret < 0) 133 return false; 134 135 if (!(caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)) 136 flag = false; 137 } 138 return flag; 139 } 140 141 static inline bool 142 eh_dev_has_burst_mode(uint8_t dev_id) 143 { 144 struct rte_event_dev_info dev_info; 145 146 rte_event_dev_info_get(dev_id, &dev_info); 147 return (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE) ? 148 true : false; 149 } 150 151 static int 152 eh_set_default_conf_eventdev(struct eventmode_conf *em_conf) 153 { 154 int lcore_count, nb_eventdev, nb_eth_dev, ret; 155 struct eventdev_params *eventdev_config; 156 struct rte_event_dev_info dev_info; 157 158 /* Get the number of event devices */ 159 nb_eventdev = rte_event_dev_count(); 160 if (nb_eventdev == 0) { 161 EH_LOG_ERR("No event devices detected"); 162 return -EINVAL; 163 } 164 165 if (nb_eventdev != 1) { 166 EH_LOG_ERR("Event mode does not support multiple event devices. " 167 "Please provide only one event device."); 168 return -EINVAL; 169 } 170 171 /* Get the number of eth devs */ 172 nb_eth_dev = rte_eth_dev_count_avail(); 173 if (nb_eth_dev == 0) { 174 EH_LOG_ERR("No eth devices detected"); 175 return -EINVAL; 176 } 177 178 /* Get the number of lcores */ 179 lcore_count = rte_lcore_count(); 180 181 /* Read event device info */ 182 ret = rte_event_dev_info_get(0, &dev_info); 183 if (ret < 0) { 184 EH_LOG_ERR("Failed to read event device info %d", ret); 185 return ret; 186 } 187 188 /* Check if enough ports are available */ 189 if (dev_info.max_event_ports < 2) { 190 EH_LOG_ERR("Not enough event ports available"); 191 return -EINVAL; 192 } 193 194 /* Get the first event dev conf */ 195 eventdev_config = &(em_conf->eventdev_config[0]); 196 197 /* Save number of queues & ports available */ 198 eventdev_config->eventdev_id = 0; 199 eventdev_config->nb_eventqueue = dev_info.max_event_queues; 200 eventdev_config->nb_eventport = dev_info.max_event_ports; 201 eventdev_config->ev_queue_mode = RTE_EVENT_QUEUE_CFG_ALL_TYPES; 202 203 /* Check if there are more queues than required */ 204 if (eventdev_config->nb_eventqueue > nb_eth_dev + 1) { 205 /* One queue is reserved for Tx */ 206 eventdev_config->nb_eventqueue = nb_eth_dev + 1; 207 } 208 209 /* Check if there are more ports than required */ 210 if (eventdev_config->nb_eventport > lcore_count) { 211 /* One port per lcore is enough */ 212 eventdev_config->nb_eventport = lcore_count; 213 } 214 215 /* Update the number of event devices */ 216 em_conf->nb_eventdev++; 217 218 return 0; 219 } 220 221 static void 222 eh_do_capability_check(struct eventmode_conf *em_conf) 223 { 224 struct eventdev_params *eventdev_config; 225 int all_internal_ports = 1; 226 uint32_t eventdev_id; 227 int i; 228 229 for (i = 0; i < em_conf->nb_eventdev; i++) { 230 231 /* Get the event dev conf */ 232 eventdev_config = &(em_conf->eventdev_config[i]); 233 eventdev_id = eventdev_config->eventdev_id; 234 235 /* Check if event device has internal port for Rx & Tx */ 236 if (eh_dev_has_rx_internal_port(eventdev_id) && 237 eh_dev_has_tx_internal_port(eventdev_id)) { 238 eventdev_config->all_internal_ports = 1; 239 } else { 240 all_internal_ports = 0; 241 } 242 } 243 244 /* 245 * If Rx & Tx internal ports are supported by all event devices then 246 * eth cores won't be required. Override the eth core mask requested 247 * and decrement number of event queues by one as it won't be needed 248 * for Tx. 249 */ 250 if (all_internal_ports) { 251 rte_bitmap_reset(em_conf->eth_core_mask); 252 for (i = 0; i < em_conf->nb_eventdev; i++) 253 em_conf->eventdev_config[i].nb_eventqueue--; 254 } 255 } 256 257 static int 258 eh_set_default_conf_link(struct eventmode_conf *em_conf) 259 { 260 struct eventdev_params *eventdev_config; 261 struct eh_event_link_info *link; 262 unsigned int lcore_id = -1; 263 int i, link_index; 264 265 /* 266 * Create a 1:1 mapping from event ports to cores. If the number 267 * of event ports is lesser than the cores, some cores won't 268 * execute worker. If there are more event ports, then some ports 269 * won't be used. 270 * 271 */ 272 273 /* 274 * The event queue-port mapping is done according to the link. Since 275 * we are falling back to the default link config, enabling 276 * "all_ev_queue_to_ev_port" mode flag. This will map all queues 277 * to the port. 278 */ 279 em_conf->ext_params.all_ev_queue_to_ev_port = 1; 280 281 /* Get first event dev conf */ 282 eventdev_config = &(em_conf->eventdev_config[0]); 283 284 /* Loop through the ports */ 285 for (i = 0; i < eventdev_config->nb_eventport; i++) { 286 287 /* Get next active core id */ 288 lcore_id = eh_get_next_active_core(em_conf, 289 lcore_id); 290 291 if (lcore_id == RTE_MAX_LCORE) { 292 /* Reached max cores */ 293 return 0; 294 } 295 296 /* Save the current combination as one link */ 297 298 /* Get the index */ 299 link_index = em_conf->nb_link; 300 301 /* Get the corresponding link */ 302 link = &(em_conf->link[link_index]); 303 304 /* Save link */ 305 link->eventdev_id = eventdev_config->eventdev_id; 306 link->event_port_id = i; 307 link->lcore_id = lcore_id; 308 309 /* 310 * Don't set eventq_id as by default all queues 311 * need to be mapped to the port, which is controlled 312 * by the operating mode. 313 */ 314 315 /* Update number of links */ 316 em_conf->nb_link++; 317 } 318 319 return 0; 320 } 321 322 static int 323 eh_set_default_conf_rx_adapter(struct eventmode_conf *em_conf) 324 { 325 struct rx_adapter_connection_info *conn; 326 struct eventdev_params *eventdev_config; 327 struct rx_adapter_conf *adapter; 328 bool rx_internal_port = true; 329 bool single_ev_queue = false; 330 int nb_eventqueue; 331 uint32_t caps = 0; 332 int eventdev_id; 333 int nb_eth_dev; 334 int adapter_id; 335 int conn_id; 336 int ret; 337 int i; 338 339 /* Create one adapter with eth queues mapped to event queue(s) */ 340 341 if (em_conf->nb_eventdev == 0) { 342 EH_LOG_ERR("No event devs registered"); 343 return -EINVAL; 344 } 345 346 /* Get the number of eth devs */ 347 nb_eth_dev = rte_eth_dev_count_avail(); 348 349 /* Use the first event dev */ 350 eventdev_config = &(em_conf->eventdev_config[0]); 351 352 /* Get eventdev ID */ 353 eventdev_id = eventdev_config->eventdev_id; 354 adapter_id = 0; 355 356 /* Get adapter conf */ 357 adapter = &(em_conf->rx_adapter[adapter_id]); 358 359 /* Set adapter conf */ 360 adapter->eventdev_id = eventdev_id; 361 adapter->adapter_id = adapter_id; 362 363 /* 364 * If event device does not have internal ports for passing 365 * packets then reserved one queue for Tx path 366 */ 367 nb_eventqueue = eventdev_config->all_internal_ports ? 368 eventdev_config->nb_eventqueue : 369 eventdev_config->nb_eventqueue - 1; 370 371 /* 372 * Map all queues of eth device (port) to an event queue. If there 373 * are more event queues than eth ports then create 1:1 mapping. 374 * Otherwise map all eth ports to a single event queue. 375 */ 376 if (nb_eth_dev > nb_eventqueue) 377 single_ev_queue = true; 378 379 for (i = 0; i < nb_eth_dev; i++) { 380 381 /* Use only the ports enabled */ 382 if ((em_conf->eth_portmask & (1 << i)) == 0) 383 continue; 384 385 /* Get the connection id */ 386 conn_id = adapter->nb_connections; 387 388 /* Get the connection */ 389 conn = &(adapter->conn[conn_id]); 390 391 /* Set mapping between eth ports & event queues*/ 392 conn->ethdev_id = i; 393 conn->eventq_id = single_ev_queue ? 0 : i; 394 395 /* Add all eth queues eth port to event queue */ 396 conn->ethdev_rx_qid = -1; 397 398 /* Get Rx adapter capabilities */ 399 ret = rte_event_eth_rx_adapter_caps_get(eventdev_id, i, &caps); 400 if (ret < 0) { 401 EH_LOG_ERR("Failed to get event device %d eth rx adapter" 402 " capabilities for port %d", eventdev_id, i); 403 return ret; 404 } 405 if (!(caps & RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT)) 406 rx_internal_port = false; 407 408 /* Update no of connections */ 409 adapter->nb_connections++; 410 411 } 412 413 if (rx_internal_port) { 414 /* Rx core is not required */ 415 adapter->rx_core_id = -1; 416 } else { 417 /* Rx core is required */ 418 adapter->rx_core_id = eh_get_next_eth_core(em_conf); 419 } 420 421 /* We have setup one adapter */ 422 em_conf->nb_rx_adapter = 1; 423 424 return 0; 425 } 426 427 static int 428 eh_set_default_conf_tx_adapter(struct eventmode_conf *em_conf) 429 { 430 struct tx_adapter_connection_info *conn; 431 struct eventdev_params *eventdev_config; 432 struct tx_adapter_conf *tx_adapter; 433 bool tx_internal_port = true; 434 uint32_t caps = 0; 435 int eventdev_id; 436 int adapter_id; 437 int nb_eth_dev; 438 int conn_id; 439 int ret; 440 int i; 441 442 /* 443 * Create one Tx adapter with all eth queues mapped to event queues 444 * 1:1. 445 */ 446 447 if (em_conf->nb_eventdev == 0) { 448 EH_LOG_ERR("No event devs registered"); 449 return -EINVAL; 450 } 451 452 /* Get the number of eth devs */ 453 nb_eth_dev = rte_eth_dev_count_avail(); 454 455 /* Use the first event dev */ 456 eventdev_config = &(em_conf->eventdev_config[0]); 457 458 /* Get eventdev ID */ 459 eventdev_id = eventdev_config->eventdev_id; 460 adapter_id = 0; 461 462 /* Get adapter conf */ 463 tx_adapter = &(em_conf->tx_adapter[adapter_id]); 464 465 /* Set adapter conf */ 466 tx_adapter->eventdev_id = eventdev_id; 467 tx_adapter->adapter_id = adapter_id; 468 469 /* 470 * Map all Tx queues of the eth device (port) to the event device. 471 */ 472 473 /* Set defaults for connections */ 474 475 /* 476 * One eth device (port) is one connection. Map all Tx queues 477 * of the device to the Tx adapter. 478 */ 479 480 for (i = 0; i < nb_eth_dev; i++) { 481 482 /* Use only the ports enabled */ 483 if ((em_conf->eth_portmask & (1 << i)) == 0) 484 continue; 485 486 /* Get the connection id */ 487 conn_id = tx_adapter->nb_connections; 488 489 /* Get the connection */ 490 conn = &(tx_adapter->conn[conn_id]); 491 492 /* Add ethdev to connections */ 493 conn->ethdev_id = i; 494 495 /* Add all eth tx queues to adapter */ 496 conn->ethdev_tx_qid = -1; 497 498 /* Get Tx adapter capabilities */ 499 ret = rte_event_eth_tx_adapter_caps_get(eventdev_id, i, &caps); 500 if (ret < 0) { 501 EH_LOG_ERR("Failed to get event device %d eth tx adapter" 502 " capabilities for port %d", eventdev_id, i); 503 return ret; 504 } 505 if (!(caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)) 506 tx_internal_port = false; 507 508 /* Update no of connections */ 509 tx_adapter->nb_connections++; 510 } 511 512 if (tx_internal_port) { 513 /* Tx core is not required */ 514 tx_adapter->tx_core_id = -1; 515 } else { 516 /* Tx core is required */ 517 tx_adapter->tx_core_id = eh_get_next_eth_core(em_conf); 518 519 /* 520 * Use one event queue per adapter for submitting packets 521 * for Tx. Reserving the last queue available 522 */ 523 /* Queue numbers start at 0 */ 524 tx_adapter->tx_ev_queue = eventdev_config->nb_eventqueue - 1; 525 } 526 527 /* We have setup one adapter */ 528 em_conf->nb_tx_adapter = 1; 529 return 0; 530 } 531 532 static int 533 eh_validate_conf(struct eventmode_conf *em_conf) 534 { 535 int ret; 536 537 /* 538 * Check if event devs are specified. Else probe the event devices 539 * and initialize the config with all ports & queues available 540 */ 541 if (em_conf->nb_eventdev == 0) { 542 ret = eh_set_default_conf_eventdev(em_conf); 543 if (ret != 0) 544 return ret; 545 } 546 547 /* Perform capability check for the selected event devices */ 548 eh_do_capability_check(em_conf); 549 550 /* 551 * Check if links are specified. Else generate a default config for 552 * the event ports used. 553 */ 554 if (em_conf->nb_link == 0) { 555 ret = eh_set_default_conf_link(em_conf); 556 if (ret != 0) 557 return ret; 558 } 559 560 /* 561 * Check if rx adapters are specified. Else generate a default config 562 * with one rx adapter and all eth queues - event queue mapped. 563 */ 564 if (em_conf->nb_rx_adapter == 0) { 565 ret = eh_set_default_conf_rx_adapter(em_conf); 566 if (ret != 0) 567 return ret; 568 } 569 570 /* 571 * Check if tx adapters are specified. Else generate a default config 572 * with one tx adapter. 573 */ 574 if (em_conf->nb_tx_adapter == 0) { 575 ret = eh_set_default_conf_tx_adapter(em_conf); 576 if (ret != 0) 577 return ret; 578 } 579 580 return 0; 581 } 582 583 static int 584 eh_initialize_eventdev(struct eventmode_conf *em_conf) 585 { 586 struct rte_event_queue_conf eventq_conf = {0}; 587 struct rte_event_dev_info evdev_default_conf; 588 struct rte_event_dev_config eventdev_conf; 589 struct eventdev_params *eventdev_config; 590 int nb_eventdev = em_conf->nb_eventdev; 591 struct eh_event_link_info *link; 592 uint8_t *queue = NULL; 593 uint8_t eventdev_id; 594 int nb_eventqueue; 595 uint8_t i, j; 596 int ret; 597 598 for (i = 0; i < nb_eventdev; i++) { 599 600 /* Get eventdev config */ 601 eventdev_config = &(em_conf->eventdev_config[i]); 602 603 /* Get event dev ID */ 604 eventdev_id = eventdev_config->eventdev_id; 605 606 /* Get the number of queues */ 607 nb_eventqueue = eventdev_config->nb_eventqueue; 608 609 /* Reset the default conf */ 610 memset(&evdev_default_conf, 0, 611 sizeof(struct rte_event_dev_info)); 612 613 /* Get default conf of eventdev */ 614 ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf); 615 if (ret < 0) { 616 EH_LOG_ERR( 617 "Error in getting event device info[devID:%d]", 618 eventdev_id); 619 return ret; 620 } 621 622 memset(&eventdev_conf, 0, sizeof(struct rte_event_dev_config)); 623 eventdev_conf.nb_events_limit = 624 evdev_default_conf.max_num_events; 625 eventdev_conf.nb_event_queues = nb_eventqueue; 626 eventdev_conf.nb_event_ports = 627 eventdev_config->nb_eventport; 628 eventdev_conf.nb_event_queue_flows = 629 evdev_default_conf.max_event_queue_flows; 630 eventdev_conf.nb_event_port_dequeue_depth = 631 evdev_default_conf.max_event_port_dequeue_depth; 632 eventdev_conf.nb_event_port_enqueue_depth = 633 evdev_default_conf.max_event_port_enqueue_depth; 634 635 /* Configure event device */ 636 ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); 637 if (ret < 0) { 638 EH_LOG_ERR("Error in configuring event device"); 639 return ret; 640 } 641 642 /* Configure event queues */ 643 for (j = 0; j < nb_eventqueue; j++) { 644 645 memset(&eventq_conf, 0, 646 sizeof(struct rte_event_queue_conf)); 647 648 /* Per event dev queues can be ATQ or SINGLE LINK */ 649 eventq_conf.event_queue_cfg = 650 eventdev_config->ev_queue_mode; 651 /* 652 * All queues need to be set with sched_type as 653 * schedule type for the application stage. One 654 * queue would be reserved for the final eth tx 655 * stage if event device does not have internal 656 * ports. This will be an atomic queue. 657 */ 658 if (!eventdev_config->all_internal_ports && 659 j == nb_eventqueue-1) { 660 eventq_conf.schedule_type = 661 RTE_SCHED_TYPE_ATOMIC; 662 } else { 663 eventq_conf.schedule_type = 664 em_conf->ext_params.sched_type; 665 } 666 667 /* Set max atomic flows to 1024 */ 668 eventq_conf.nb_atomic_flows = 1024; 669 eventq_conf.nb_atomic_order_sequences = 1024; 670 671 /* Setup the queue */ 672 ret = rte_event_queue_setup(eventdev_id, j, 673 &eventq_conf); 674 if (ret < 0) { 675 EH_LOG_ERR("Failed to setup event queue %d", 676 ret); 677 return ret; 678 } 679 } 680 681 /* Configure event ports */ 682 for (j = 0; j < eventdev_config->nb_eventport; j++) { 683 ret = rte_event_port_setup(eventdev_id, j, NULL); 684 if (ret < 0) { 685 EH_LOG_ERR("Failed to setup event port %d", 686 ret); 687 return ret; 688 } 689 } 690 } 691 692 /* Make event queue - event port link */ 693 for (j = 0; j < em_conf->nb_link; j++) { 694 695 /* Get link info */ 696 link = &(em_conf->link[j]); 697 698 /* Get event dev ID */ 699 eventdev_id = link->eventdev_id; 700 701 /* 702 * If "all_ev_queue_to_ev_port" params flag is selected, all 703 * queues need to be mapped to the port. 704 */ 705 if (em_conf->ext_params.all_ev_queue_to_ev_port) 706 queue = NULL; 707 else 708 queue = &(link->eventq_id); 709 710 /* Link queue to port */ 711 ret = rte_event_port_link(eventdev_id, link->event_port_id, 712 queue, NULL, 1); 713 if (ret < 0) { 714 EH_LOG_ERR("Failed to link event port %d", ret); 715 return ret; 716 } 717 } 718 719 return 0; 720 } 721 722 static int 723 eh_start_eventdev(struct eventmode_conf *em_conf) 724 { 725 struct eventdev_params *eventdev_config; 726 int nb_eventdev = em_conf->nb_eventdev; 727 int i, ret; 728 729 /* Start event devices */ 730 for (i = 0; i < nb_eventdev; i++) { 731 732 /* Get eventdev config */ 733 eventdev_config = &(em_conf->eventdev_config[i]); 734 735 ret = rte_event_dev_start(eventdev_config->eventdev_id); 736 if (ret < 0) { 737 EH_LOG_ERR("Failed to start event device %d, %d", 738 i, ret); 739 return ret; 740 } 741 } 742 return 0; 743 } 744 745 static int 746 eh_event_vector_limits_validate(struct eventmode_conf *em_conf, 747 uint8_t ev_dev_id, uint8_t ethdev_id) 748 { 749 struct rte_event_eth_rx_adapter_vector_limits limits = {0}; 750 uint16_t vector_size = em_conf->ext_params.vector_size; 751 int ret; 752 753 ret = rte_event_eth_rx_adapter_vector_limits_get(ev_dev_id, ethdev_id, 754 &limits); 755 if (ret) { 756 EH_LOG_ERR("failed to get vector limits"); 757 return ret; 758 } 759 760 if (vector_size < limits.min_sz || vector_size > limits.max_sz) { 761 EH_LOG_ERR("Vector size [%d] not within limits min[%d] max[%d]", 762 vector_size, limits.min_sz, limits.max_sz); 763 return -EINVAL; 764 } 765 766 if (limits.log2_sz && !rte_is_power_of_2(vector_size)) { 767 EH_LOG_ERR("Vector size [%d] not power of 2", vector_size); 768 return -EINVAL; 769 } 770 771 if (em_conf->vector_tmo_ns > limits.max_timeout_ns || 772 em_conf->vector_tmo_ns < limits.min_timeout_ns) { 773 EH_LOG_ERR("Vector timeout [%" PRIu64 774 "] not within limits max[%" PRIu64 775 "] min[%" PRIu64 "]", 776 em_conf->vector_tmo_ns, 777 limits.max_timeout_ns, 778 limits.min_timeout_ns); 779 return -EINVAL; 780 } 781 return 0; 782 } 783 784 static int 785 eh_rx_adapter_configure(struct eventmode_conf *em_conf, 786 struct rx_adapter_conf *adapter) 787 { 788 struct rte_event_eth_rx_adapter_queue_conf queue_conf = {0}; 789 struct rte_event_dev_info evdev_default_conf = {0}; 790 struct rte_event_port_conf port_conf = {0}; 791 struct rx_adapter_connection_info *conn; 792 uint32_t service_id, socket_id, nb_elem; 793 struct rte_mempool *vector_pool = NULL; 794 uint32_t lcore_id = rte_lcore_id(); 795 int ret, portid, nb_ports = 0; 796 uint8_t eventdev_id; 797 int j; 798 799 /* Get event dev ID */ 800 eventdev_id = adapter->eventdev_id; 801 802 /* Get default configuration of event dev */ 803 ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf); 804 if (ret < 0) { 805 EH_LOG_ERR("Failed to get event dev info %d", ret); 806 return ret; 807 } 808 809 RTE_ETH_FOREACH_DEV(portid) 810 if ((em_conf->eth_portmask & (1 << portid))) 811 nb_ports++; 812 813 if (em_conf->ext_params.event_vector) { 814 socket_id = rte_lcore_to_socket_id(lcore_id); 815 816 if (em_conf->vector_pool_sz) { 817 nb_elem = em_conf->vector_pool_sz; 818 } else { 819 nb_elem = (nb_bufs_in_pool / 820 em_conf->ext_params.vector_size) + 1; 821 if (per_port_pool) 822 nb_elem = nb_ports * nb_elem; 823 } 824 825 vector_pool = rte_event_vector_pool_create( 826 "vector_pool", nb_elem, 0, 827 em_conf->ext_params.vector_size, 828 socket_id); 829 if (vector_pool == NULL) { 830 EH_LOG_ERR("failed to create event vector pool"); 831 return -ENOMEM; 832 } 833 } 834 /* Setup port conf */ 835 port_conf.new_event_threshold = 1200; 836 port_conf.dequeue_depth = 837 evdev_default_conf.max_event_port_dequeue_depth; 838 port_conf.enqueue_depth = 839 evdev_default_conf.max_event_port_enqueue_depth; 840 841 /* Create Rx adapter */ 842 ret = rte_event_eth_rx_adapter_create(adapter->adapter_id, 843 adapter->eventdev_id, &port_conf); 844 if (ret < 0) { 845 EH_LOG_ERR("Failed to create rx adapter %d", ret); 846 return ret; 847 } 848 849 /* Setup various connections in the adapter */ 850 for (j = 0; j < adapter->nb_connections; j++) { 851 /* Get connection */ 852 conn = &(adapter->conn[j]); 853 854 /* Setup queue conf */ 855 queue_conf.ev.queue_id = conn->eventq_id; 856 queue_conf.ev.sched_type = em_conf->ext_params.sched_type; 857 queue_conf.ev.event_type = RTE_EVENT_TYPE_ETHDEV; 858 859 if (em_conf->ext_params.event_vector) { 860 ret = eh_event_vector_limits_validate(em_conf, 861 eventdev_id, 862 conn->ethdev_id); 863 if (ret) 864 return ret; 865 866 queue_conf.vector_sz = em_conf->ext_params.vector_size; 867 queue_conf.vector_timeout_ns = em_conf->vector_tmo_ns; 868 queue_conf.vector_mp = vector_pool; 869 queue_conf.rx_queue_flags = 870 RTE_EVENT_ETH_RX_ADAPTER_QUEUE_EVENT_VECTOR; 871 } 872 873 /* Add queue to the adapter */ 874 ret = rte_event_eth_rx_adapter_queue_add(adapter->adapter_id, 875 conn->ethdev_id, conn->ethdev_rx_qid, 876 &queue_conf); 877 if (ret < 0) { 878 EH_LOG_ERR("Failed to add eth queue to rx adapter %d", 879 ret); 880 return ret; 881 } 882 } 883 884 /* Get the service ID used by rx adapter */ 885 ret = rte_event_eth_rx_adapter_service_id_get(adapter->adapter_id, 886 &service_id); 887 if (ret != -ESRCH && ret < 0) { 888 EH_LOG_ERR("Failed to get service id used by rx adapter %d", 889 ret); 890 return ret; 891 } 892 893 rte_service_set_runstate_mapped_check(service_id, 0); 894 895 /* Start adapter */ 896 ret = rte_event_eth_rx_adapter_start(adapter->adapter_id); 897 if (ret < 0) { 898 EH_LOG_ERR("Failed to start rx adapter %d", ret); 899 return ret; 900 } 901 902 return 0; 903 } 904 905 static int 906 eh_initialize_rx_adapter(struct eventmode_conf *em_conf) 907 { 908 struct rx_adapter_conf *adapter; 909 int i, ret; 910 911 /* Configure rx adapters */ 912 for (i = 0; i < em_conf->nb_rx_adapter; i++) { 913 adapter = &(em_conf->rx_adapter[i]); 914 ret = eh_rx_adapter_configure(em_conf, adapter); 915 if (ret < 0) { 916 EH_LOG_ERR("Failed to configure rx adapter %d", ret); 917 return ret; 918 } 919 } 920 return 0; 921 } 922 923 static int32_t 924 eh_start_worker_eth_core(struct eventmode_conf *conf, uint32_t lcore_id) 925 { 926 uint32_t service_id[EVENT_MODE_MAX_ADAPTERS_PER_RX_CORE]; 927 struct rx_adapter_conf *rx_adapter; 928 struct tx_adapter_conf *tx_adapter; 929 int service_count = 0; 930 int adapter_id; 931 int32_t ret; 932 int i; 933 934 EH_LOG_INFO("Entering eth_core processing on lcore %u", lcore_id); 935 936 /* 937 * Parse adapter config to check which of all Rx adapters need 938 * to be handled by this core. 939 */ 940 for (i = 0; i < conf->nb_rx_adapter; i++) { 941 /* Check if we have exceeded the max allowed */ 942 if (service_count > EVENT_MODE_MAX_ADAPTERS_PER_RX_CORE) { 943 EH_LOG_ERR( 944 "Exceeded the max allowed adapters per rx core"); 945 break; 946 } 947 948 rx_adapter = &(conf->rx_adapter[i]); 949 if (rx_adapter->rx_core_id != lcore_id) 950 continue; 951 952 /* Adapter is handled by this core */ 953 adapter_id = rx_adapter->adapter_id; 954 955 /* Get the service ID for the adapters */ 956 ret = rte_event_eth_rx_adapter_service_id_get(adapter_id, 957 &(service_id[service_count])); 958 959 if (ret != -ESRCH && ret < 0) { 960 EH_LOG_ERR( 961 "Failed to get service id used by rx adapter"); 962 return ret; 963 } 964 965 /* Update service count */ 966 service_count++; 967 } 968 969 /* 970 * Parse adapter config to see which of all Tx adapters need 971 * to be handled by this core. 972 */ 973 for (i = 0; i < conf->nb_tx_adapter; i++) { 974 /* Check if we have exceeded the max allowed */ 975 if (service_count > EVENT_MODE_MAX_ADAPTERS_PER_TX_CORE) { 976 EH_LOG_ERR( 977 "Exceeded the max allowed adapters per tx core"); 978 break; 979 } 980 981 tx_adapter = &conf->tx_adapter[i]; 982 if (tx_adapter->tx_core_id != lcore_id) 983 continue; 984 985 /* Adapter is handled by this core */ 986 adapter_id = tx_adapter->adapter_id; 987 988 /* Get the service ID for the adapters */ 989 ret = rte_event_eth_tx_adapter_service_id_get(adapter_id, 990 &(service_id[service_count])); 991 992 if (ret != -ESRCH && ret < 0) { 993 EH_LOG_ERR( 994 "Failed to get service id used by tx adapter"); 995 return ret; 996 } 997 998 /* Update service count */ 999 service_count++; 1000 } 1001 1002 eth_core_running = true; 1003 1004 while (eth_core_running) { 1005 for (i = 0; i < service_count; i++) { 1006 /* Initiate adapter service */ 1007 rte_service_run_iter_on_app_lcore(service_id[i], 0); 1008 } 1009 } 1010 1011 return 0; 1012 } 1013 1014 static int32_t 1015 eh_stop_worker_eth_core(void) 1016 { 1017 if (eth_core_running) { 1018 EH_LOG_INFO("Stopping eth cores"); 1019 eth_core_running = false; 1020 } 1021 return 0; 1022 } 1023 1024 static struct eh_app_worker_params * 1025 eh_find_worker(uint32_t lcore_id, struct eh_conf *conf, 1026 struct eh_app_worker_params *app_wrkrs, uint8_t nb_wrkr_param) 1027 { 1028 struct eh_app_worker_params curr_conf = { {{0} }, NULL}; 1029 struct eh_event_link_info *link = NULL; 1030 struct eh_app_worker_params *tmp_wrkr; 1031 struct eventmode_conf *em_conf; 1032 uint8_t eventdev_id; 1033 int i; 1034 1035 /* Get eventmode config */ 1036 em_conf = conf->mode_params; 1037 1038 /* 1039 * Use event device from the first lcore-event link. 1040 * 1041 * Assumption: All lcore-event links tied to a core are using the 1042 * same event device. In other words, one core would be polling on 1043 * queues of a single event device only. 1044 */ 1045 1046 /* Get a link for this lcore */ 1047 for (i = 0; i < em_conf->nb_link; i++) { 1048 link = &(em_conf->link[i]); 1049 if (link->lcore_id == lcore_id) 1050 break; 1051 } 1052 1053 if (link == NULL) { 1054 EH_LOG_ERR("No valid link found for lcore %d", lcore_id); 1055 return NULL; 1056 } 1057 1058 /* Get event dev ID */ 1059 eventdev_id = link->eventdev_id; 1060 1061 /* Populate the curr_conf with the capabilities */ 1062 1063 /* Check for Tx internal port */ 1064 if (eh_dev_has_tx_internal_port(eventdev_id)) 1065 curr_conf.cap.tx_internal_port = EH_TX_TYPE_INTERNAL_PORT; 1066 else 1067 curr_conf.cap.tx_internal_port = EH_TX_TYPE_NO_INTERNAL_PORT; 1068 1069 /* Check for burst mode */ 1070 if (eh_dev_has_burst_mode(eventdev_id)) 1071 curr_conf.cap.burst = EH_RX_TYPE_BURST; 1072 else 1073 curr_conf.cap.burst = EH_RX_TYPE_NON_BURST; 1074 1075 curr_conf.cap.ipsec_mode = conf->ipsec_mode; 1076 1077 /* Parse the passed list and see if we have matching capabilities */ 1078 1079 /* Initialize the pointer used to traverse the list */ 1080 tmp_wrkr = app_wrkrs; 1081 1082 for (i = 0; i < nb_wrkr_param; i++, tmp_wrkr++) { 1083 1084 /* Skip this if capabilities are not matching */ 1085 if (tmp_wrkr->cap.u64 != curr_conf.cap.u64) 1086 continue; 1087 1088 /* If the checks pass, we have a match */ 1089 return tmp_wrkr; 1090 } 1091 1092 return NULL; 1093 } 1094 1095 static int 1096 eh_verify_match_worker(struct eh_app_worker_params *match_wrkr) 1097 { 1098 /* Verify registered worker */ 1099 if (match_wrkr->worker_thread == NULL) { 1100 EH_LOG_ERR("No worker registered"); 1101 return 0; 1102 } 1103 1104 /* Success */ 1105 return 1; 1106 } 1107 1108 static uint8_t 1109 eh_get_event_lcore_links(uint32_t lcore_id, struct eh_conf *conf, 1110 struct eh_event_link_info **links) 1111 { 1112 struct eh_event_link_info *link_cache; 1113 struct eventmode_conf *em_conf = NULL; 1114 struct eh_event_link_info *link; 1115 uint8_t lcore_nb_link = 0; 1116 size_t single_link_size; 1117 size_t cache_size; 1118 int index = 0; 1119 int i; 1120 1121 if (conf == NULL || links == NULL) { 1122 EH_LOG_ERR("Invalid args"); 1123 return -EINVAL; 1124 } 1125 1126 /* Get eventmode conf */ 1127 em_conf = conf->mode_params; 1128 1129 if (em_conf == NULL) { 1130 EH_LOG_ERR("Invalid event mode parameters"); 1131 return -EINVAL; 1132 } 1133 1134 /* Get the number of links registered */ 1135 for (i = 0; i < em_conf->nb_link; i++) { 1136 1137 /* Get link */ 1138 link = &(em_conf->link[i]); 1139 1140 /* Check if we have link intended for this lcore */ 1141 if (link->lcore_id == lcore_id) { 1142 1143 /* Update the number of links for this core */ 1144 lcore_nb_link++; 1145 1146 } 1147 } 1148 1149 /* Compute size of one entry to be copied */ 1150 single_link_size = sizeof(struct eh_event_link_info); 1151 1152 /* Compute size of the buffer required */ 1153 cache_size = lcore_nb_link * sizeof(struct eh_event_link_info); 1154 1155 /* Compute size of the buffer required */ 1156 link_cache = calloc(1, cache_size); 1157 1158 /* Get the number of links registered */ 1159 for (i = 0; i < em_conf->nb_link; i++) { 1160 1161 /* Get link */ 1162 link = &(em_conf->link[i]); 1163 1164 /* Check if we have link intended for this lcore */ 1165 if (link->lcore_id == lcore_id) { 1166 1167 /* Cache the link */ 1168 memcpy(&link_cache[index], link, single_link_size); 1169 1170 /* Update index */ 1171 index++; 1172 } 1173 } 1174 1175 /* Update the links for application to use the cached links */ 1176 *links = link_cache; 1177 1178 /* Return the number of cached links */ 1179 return lcore_nb_link; 1180 } 1181 1182 static int 1183 eh_tx_adapter_configure(struct eventmode_conf *em_conf, 1184 struct tx_adapter_conf *adapter) 1185 { 1186 struct rte_event_dev_info evdev_default_conf = {0}; 1187 struct rte_event_port_conf port_conf = {0}; 1188 struct tx_adapter_connection_info *conn; 1189 struct eventdev_params *eventdev_config; 1190 uint8_t tx_port_id = 0; 1191 uint8_t eventdev_id; 1192 uint32_t service_id; 1193 int ret, j; 1194 1195 /* Get event dev ID */ 1196 eventdev_id = adapter->eventdev_id; 1197 1198 /* Get event device conf */ 1199 eventdev_config = eh_get_eventdev_params(em_conf, eventdev_id); 1200 1201 /* Create Tx adapter */ 1202 1203 /* Get default configuration of event dev */ 1204 ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf); 1205 if (ret < 0) { 1206 EH_LOG_ERR("Failed to get event dev info %d", ret); 1207 return ret; 1208 } 1209 1210 /* Setup port conf */ 1211 port_conf.new_event_threshold = 1212 evdev_default_conf.max_num_events; 1213 port_conf.dequeue_depth = 1214 evdev_default_conf.max_event_port_dequeue_depth; 1215 port_conf.enqueue_depth = 1216 evdev_default_conf.max_event_port_enqueue_depth; 1217 1218 /* Create adapter */ 1219 ret = rte_event_eth_tx_adapter_create(adapter->adapter_id, 1220 adapter->eventdev_id, &port_conf); 1221 if (ret < 0) { 1222 EH_LOG_ERR("Failed to create tx adapter %d", ret); 1223 return ret; 1224 } 1225 1226 /* Setup various connections in the adapter */ 1227 for (j = 0; j < adapter->nb_connections; j++) { 1228 1229 /* Get connection */ 1230 conn = &(adapter->conn[j]); 1231 1232 /* Add queue to the adapter */ 1233 ret = rte_event_eth_tx_adapter_queue_add(adapter->adapter_id, 1234 conn->ethdev_id, conn->ethdev_tx_qid); 1235 if (ret < 0) { 1236 EH_LOG_ERR("Failed to add eth queue to tx adapter %d", 1237 ret); 1238 return ret; 1239 } 1240 } 1241 1242 /* 1243 * Check if Tx core is assigned. If Tx core is not assigned then 1244 * the adapter has internal port for submitting Tx packets and 1245 * Tx event queue & port setup is not required 1246 */ 1247 if (adapter->tx_core_id == (uint32_t) (-1)) { 1248 /* Internal port is present */ 1249 goto skip_tx_queue_port_setup; 1250 } 1251 1252 /* Setup Tx queue & port */ 1253 1254 /* Get event port used by the adapter */ 1255 ret = rte_event_eth_tx_adapter_event_port_get( 1256 adapter->adapter_id, &tx_port_id); 1257 if (ret) { 1258 EH_LOG_ERR("Failed to get tx adapter port id %d", ret); 1259 return ret; 1260 } 1261 1262 /* 1263 * Tx event queue is reserved for Tx adapter. Unlink this queue 1264 * from all other ports 1265 * 1266 */ 1267 for (j = 0; j < eventdev_config->nb_eventport; j++) { 1268 rte_event_port_unlink(eventdev_id, j, 1269 &(adapter->tx_ev_queue), 1); 1270 } 1271 1272 /* Link Tx event queue to Tx port */ 1273 ret = rte_event_port_link(eventdev_id, tx_port_id, 1274 &(adapter->tx_ev_queue), NULL, 1); 1275 if (ret != 1) { 1276 EH_LOG_ERR("Failed to link event queue to port"); 1277 return ret; 1278 } 1279 1280 /* Get the service ID used by Tx adapter */ 1281 ret = rte_event_eth_tx_adapter_service_id_get(adapter->adapter_id, 1282 &service_id); 1283 if (ret != -ESRCH && ret < 0) { 1284 EH_LOG_ERR("Failed to get service id used by tx adapter %d", 1285 ret); 1286 return ret; 1287 } 1288 1289 rte_service_set_runstate_mapped_check(service_id, 0); 1290 1291 skip_tx_queue_port_setup: 1292 /* Start adapter */ 1293 ret = rte_event_eth_tx_adapter_start(adapter->adapter_id); 1294 if (ret < 0) { 1295 EH_LOG_ERR("Failed to start tx adapter %d", ret); 1296 return ret; 1297 } 1298 1299 return 0; 1300 } 1301 1302 static int 1303 eh_initialize_tx_adapter(struct eventmode_conf *em_conf) 1304 { 1305 struct tx_adapter_conf *adapter; 1306 int i, ret; 1307 1308 /* Configure Tx adapters */ 1309 for (i = 0; i < em_conf->nb_tx_adapter; i++) { 1310 adapter = &(em_conf->tx_adapter[i]); 1311 ret = eh_tx_adapter_configure(em_conf, adapter); 1312 if (ret < 0) { 1313 EH_LOG_ERR("Failed to configure tx adapter %d", ret); 1314 return ret; 1315 } 1316 } 1317 return 0; 1318 } 1319 1320 static void 1321 eh_display_operating_mode(struct eventmode_conf *em_conf) 1322 { 1323 char sched_types[][32] = { 1324 "RTE_SCHED_TYPE_ORDERED", 1325 "RTE_SCHED_TYPE_ATOMIC", 1326 "RTE_SCHED_TYPE_PARALLEL", 1327 }; 1328 EH_LOG_INFO("Operating mode:"); 1329 1330 EH_LOG_INFO("\tScheduling type: \t%s", 1331 sched_types[em_conf->ext_params.sched_type]); 1332 1333 EH_LOG_INFO(""); 1334 } 1335 1336 static void 1337 eh_display_event_dev_conf(struct eventmode_conf *em_conf) 1338 { 1339 char queue_mode[][32] = { 1340 "", 1341 "ATQ (ALL TYPE QUEUE)", 1342 "SINGLE LINK", 1343 }; 1344 char print_buf[256] = { 0 }; 1345 int i; 1346 1347 EH_LOG_INFO("Event Device Configuration:"); 1348 1349 for (i = 0; i < em_conf->nb_eventdev; i++) { 1350 sprintf(print_buf, 1351 "\tDev ID: %-2d \tQueues: %-2d \tPorts: %-2d", 1352 em_conf->eventdev_config[i].eventdev_id, 1353 em_conf->eventdev_config[i].nb_eventqueue, 1354 em_conf->eventdev_config[i].nb_eventport); 1355 sprintf(print_buf + strlen(print_buf), 1356 "\tQueue mode: %s", 1357 queue_mode[em_conf->eventdev_config[i].ev_queue_mode]); 1358 EH_LOG_INFO("%s", print_buf); 1359 } 1360 EH_LOG_INFO(""); 1361 } 1362 1363 static void 1364 eh_display_rx_adapter_conf(struct eventmode_conf *em_conf) 1365 { 1366 int nb_rx_adapter = em_conf->nb_rx_adapter; 1367 struct rx_adapter_connection_info *conn; 1368 struct rx_adapter_conf *adapter; 1369 char print_buf[256] = { 0 }; 1370 int i, j; 1371 1372 EH_LOG_INFO("Rx adapters configured: %d", nb_rx_adapter); 1373 1374 for (i = 0; i < nb_rx_adapter; i++) { 1375 adapter = &(em_conf->rx_adapter[i]); 1376 sprintf(print_buf, 1377 "\tRx adapter ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d", 1378 adapter->adapter_id, 1379 adapter->nb_connections, 1380 adapter->eventdev_id); 1381 if (adapter->rx_core_id == (uint32_t)-1) 1382 sprintf(print_buf + strlen(print_buf), 1383 "\tRx core: %-2s", "[INTERNAL PORT]"); 1384 else if (adapter->rx_core_id == RTE_MAX_LCORE) 1385 sprintf(print_buf + strlen(print_buf), 1386 "\tRx core: %-2s", "[NONE]"); 1387 else 1388 sprintf(print_buf + strlen(print_buf), 1389 "\tRx core: %-2d", adapter->rx_core_id); 1390 1391 EH_LOG_INFO("%s", print_buf); 1392 1393 for (j = 0; j < adapter->nb_connections; j++) { 1394 conn = &(adapter->conn[j]); 1395 1396 sprintf(print_buf, 1397 "\t\tEthdev ID: %-2d", conn->ethdev_id); 1398 1399 if (conn->ethdev_rx_qid == -1) 1400 sprintf(print_buf + strlen(print_buf), 1401 "\tEth rx queue: %-2s", "ALL"); 1402 else 1403 sprintf(print_buf + strlen(print_buf), 1404 "\tEth rx queue: %-2d", 1405 conn->ethdev_rx_qid); 1406 1407 sprintf(print_buf + strlen(print_buf), 1408 "\tEvent queue: %-2d", conn->eventq_id); 1409 EH_LOG_INFO("%s", print_buf); 1410 } 1411 } 1412 EH_LOG_INFO(""); 1413 } 1414 1415 static void 1416 eh_display_tx_adapter_conf(struct eventmode_conf *em_conf) 1417 { 1418 int nb_tx_adapter = em_conf->nb_tx_adapter; 1419 struct tx_adapter_connection_info *conn; 1420 struct tx_adapter_conf *adapter; 1421 char print_buf[256] = { 0 }; 1422 int i, j; 1423 1424 EH_LOG_INFO("Tx adapters configured: %d", nb_tx_adapter); 1425 1426 for (i = 0; i < nb_tx_adapter; i++) { 1427 adapter = &(em_conf->tx_adapter[i]); 1428 sprintf(print_buf, 1429 "\tTx adapter ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d", 1430 adapter->adapter_id, 1431 adapter->nb_connections, 1432 adapter->eventdev_id); 1433 if (adapter->tx_core_id == (uint32_t)-1) 1434 sprintf(print_buf + strlen(print_buf), 1435 "\tTx core: %-2s", "[INTERNAL PORT]"); 1436 else if (adapter->tx_core_id == RTE_MAX_LCORE) 1437 sprintf(print_buf + strlen(print_buf), 1438 "\tTx core: %-2s", "[NONE]"); 1439 else 1440 sprintf(print_buf + strlen(print_buf), 1441 "\tTx core: %-2d,\tInput event queue: %-2d", 1442 adapter->tx_core_id, adapter->tx_ev_queue); 1443 1444 EH_LOG_INFO("%s", print_buf); 1445 1446 for (j = 0; j < adapter->nb_connections; j++) { 1447 conn = &(adapter->conn[j]); 1448 1449 sprintf(print_buf, 1450 "\t\tEthdev ID: %-2d", conn->ethdev_id); 1451 1452 if (conn->ethdev_tx_qid == -1) 1453 sprintf(print_buf + strlen(print_buf), 1454 "\tEth tx queue: %-2s", "ALL"); 1455 else 1456 sprintf(print_buf + strlen(print_buf), 1457 "\tEth tx queue: %-2d", 1458 conn->ethdev_tx_qid); 1459 EH_LOG_INFO("%s", print_buf); 1460 } 1461 } 1462 EH_LOG_INFO(""); 1463 } 1464 1465 static void 1466 eh_display_link_conf(struct eventmode_conf *em_conf) 1467 { 1468 struct eh_event_link_info *link; 1469 char print_buf[256] = { 0 }; 1470 int i; 1471 1472 EH_LOG_INFO("Links configured: %d", em_conf->nb_link); 1473 1474 for (i = 0; i < em_conf->nb_link; i++) { 1475 link = &(em_conf->link[i]); 1476 1477 sprintf(print_buf, 1478 "\tEvent dev ID: %-2d\tEvent port: %-2d", 1479 link->eventdev_id, 1480 link->event_port_id); 1481 1482 if (em_conf->ext_params.all_ev_queue_to_ev_port) 1483 sprintf(print_buf + strlen(print_buf), 1484 "Event queue: %-2s\t", "ALL"); 1485 else 1486 sprintf(print_buf + strlen(print_buf), 1487 "Event queue: %-2d\t", link->eventq_id); 1488 1489 sprintf(print_buf + strlen(print_buf), 1490 "Lcore: %-2d", link->lcore_id); 1491 EH_LOG_INFO("%s", print_buf); 1492 } 1493 EH_LOG_INFO(""); 1494 } 1495 1496 struct eh_conf * 1497 eh_conf_init(void) 1498 { 1499 struct eventmode_conf *em_conf = NULL; 1500 struct eh_conf *conf = NULL; 1501 unsigned int eth_core_id; 1502 void *bitmap = NULL; 1503 uint32_t nb_bytes; 1504 1505 /* Allocate memory for config */ 1506 conf = calloc(1, sizeof(struct eh_conf)); 1507 if (conf == NULL) { 1508 EH_LOG_ERR("Failed to allocate memory for eventmode helper " 1509 "config"); 1510 return NULL; 1511 } 1512 1513 /* Set default conf */ 1514 1515 /* Packet transfer mode: poll */ 1516 conf->mode = EH_PKT_TRANSFER_MODE_POLL; 1517 conf->ipsec_mode = EH_IPSEC_MODE_TYPE_APP; 1518 1519 /* Keep all ethernet ports enabled by default */ 1520 conf->eth_portmask = -1; 1521 1522 /* Allocate memory for event mode params */ 1523 conf->mode_params = calloc(1, sizeof(struct eventmode_conf)); 1524 if (conf->mode_params == NULL) { 1525 EH_LOG_ERR("Failed to allocate memory for event mode params"); 1526 goto free_conf; 1527 } 1528 1529 /* Get eventmode conf */ 1530 em_conf = conf->mode_params; 1531 1532 /* Allocate and initialize bitmap for eth cores */ 1533 nb_bytes = rte_bitmap_get_memory_footprint(RTE_MAX_LCORE); 1534 if (!nb_bytes) { 1535 EH_LOG_ERR("Failed to get bitmap footprint"); 1536 goto free_em_conf; 1537 } 1538 1539 bitmap = rte_zmalloc("event-helper-ethcore-bitmap", nb_bytes, 1540 RTE_CACHE_LINE_SIZE); 1541 if (!bitmap) { 1542 EH_LOG_ERR("Failed to allocate memory for eth cores bitmap\n"); 1543 goto free_em_conf; 1544 } 1545 1546 em_conf->eth_core_mask = rte_bitmap_init(RTE_MAX_LCORE, bitmap, 1547 nb_bytes); 1548 if (!em_conf->eth_core_mask) { 1549 EH_LOG_ERR("Failed to initialize bitmap"); 1550 goto free_bitmap; 1551 } 1552 1553 /* Set schedule type as not set */ 1554 em_conf->ext_params.sched_type = SCHED_TYPE_NOT_SET; 1555 1556 /* Set two cores as eth cores for Rx & Tx */ 1557 1558 /* Use first core other than main core as Rx core */ 1559 eth_core_id = rte_get_next_lcore(0, /* curr core */ 1560 1, /* skip main core */ 1561 0 /* wrap */); 1562 1563 rte_bitmap_set(em_conf->eth_core_mask, eth_core_id); 1564 1565 /* Use next core as Tx core */ 1566 eth_core_id = rte_get_next_lcore(eth_core_id, /* curr core */ 1567 1, /* skip main core */ 1568 0 /* wrap */); 1569 1570 rte_bitmap_set(em_conf->eth_core_mask, eth_core_id); 1571 1572 em_conf->ext_params.vector_size = DEFAULT_VECTOR_SIZE; 1573 em_conf->vector_tmo_ns = DEFAULT_VECTOR_TMO; 1574 1575 return conf; 1576 1577 free_bitmap: 1578 rte_free(bitmap); 1579 free_em_conf: 1580 free(em_conf); 1581 free_conf: 1582 free(conf); 1583 return NULL; 1584 } 1585 1586 void 1587 eh_conf_uninit(struct eh_conf *conf) 1588 { 1589 struct eventmode_conf *em_conf = NULL; 1590 1591 if (!conf || !conf->mode_params) 1592 return; 1593 1594 /* Get eventmode conf */ 1595 em_conf = conf->mode_params; 1596 1597 /* Free evenmode configuration memory */ 1598 rte_free(em_conf->eth_core_mask); 1599 free(em_conf); 1600 free(conf); 1601 } 1602 1603 void 1604 eh_display_conf(struct eh_conf *conf) 1605 { 1606 struct eventmode_conf *em_conf; 1607 1608 if (conf == NULL) { 1609 EH_LOG_ERR("Invalid event helper configuration"); 1610 return; 1611 } 1612 1613 if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT) 1614 return; 1615 1616 if (conf->mode_params == NULL) { 1617 EH_LOG_ERR("Invalid event mode parameters"); 1618 return; 1619 } 1620 1621 /* Get eventmode conf */ 1622 em_conf = (struct eventmode_conf *)(conf->mode_params); 1623 1624 /* Display user exposed operating modes */ 1625 eh_display_operating_mode(em_conf); 1626 1627 /* Display event device conf */ 1628 eh_display_event_dev_conf(em_conf); 1629 1630 /* Display Rx adapter conf */ 1631 eh_display_rx_adapter_conf(em_conf); 1632 1633 /* Display Tx adapter conf */ 1634 eh_display_tx_adapter_conf(em_conf); 1635 1636 /* Display event-lcore link */ 1637 eh_display_link_conf(em_conf); 1638 } 1639 1640 int32_t 1641 eh_devs_init(struct eh_conf *conf) 1642 { 1643 struct eventmode_conf *em_conf; 1644 uint16_t port_id; 1645 int ret; 1646 1647 if (conf == NULL) { 1648 EH_LOG_ERR("Invalid event helper configuration"); 1649 return -EINVAL; 1650 } 1651 1652 if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT) 1653 return 0; 1654 1655 if (conf->mode_params == NULL) { 1656 EH_LOG_ERR("Invalid event mode parameters"); 1657 return -EINVAL; 1658 } 1659 1660 /* Get eventmode conf */ 1661 em_conf = conf->mode_params; 1662 1663 /* Eventmode conf would need eth portmask */ 1664 em_conf->eth_portmask = conf->eth_portmask; 1665 1666 /* Validate the requested config */ 1667 ret = eh_validate_conf(em_conf); 1668 if (ret < 0) { 1669 EH_LOG_ERR("Failed to validate the requested config %d", ret); 1670 return ret; 1671 } 1672 1673 /* Display the current configuration */ 1674 eh_display_conf(conf); 1675 1676 /* Stop eth devices before setting up adapter */ 1677 RTE_ETH_FOREACH_DEV(port_id) { 1678 1679 /* Use only the ports enabled */ 1680 if ((conf->eth_portmask & (1 << port_id)) == 0) 1681 continue; 1682 1683 ret = rte_eth_dev_stop(port_id); 1684 if (ret != 0) { 1685 EH_LOG_ERR("Failed to stop port %u, err: %d", 1686 port_id, ret); 1687 return ret; 1688 } 1689 } 1690 1691 /* Setup eventdev */ 1692 ret = eh_initialize_eventdev(em_conf); 1693 if (ret < 0) { 1694 EH_LOG_ERR("Failed to initialize event dev %d", ret); 1695 return ret; 1696 } 1697 1698 /* Setup Rx adapter */ 1699 ret = eh_initialize_rx_adapter(em_conf); 1700 if (ret < 0) { 1701 EH_LOG_ERR("Failed to initialize rx adapter %d", ret); 1702 return ret; 1703 } 1704 1705 /* Setup Tx adapter */ 1706 ret = eh_initialize_tx_adapter(em_conf); 1707 if (ret < 0) { 1708 EH_LOG_ERR("Failed to initialize tx adapter %d", ret); 1709 return ret; 1710 } 1711 1712 /* Start eventdev */ 1713 ret = eh_start_eventdev(em_conf); 1714 if (ret < 0) { 1715 EH_LOG_ERR("Failed to start event dev %d", ret); 1716 return ret; 1717 } 1718 1719 /* Start eth devices after setting up adapter */ 1720 RTE_ETH_FOREACH_DEV(port_id) { 1721 1722 /* Use only the ports enabled */ 1723 if ((conf->eth_portmask & (1 << port_id)) == 0) 1724 continue; 1725 1726 ret = rte_eth_dev_start(port_id); 1727 if (ret < 0) { 1728 EH_LOG_ERR("Failed to start eth dev %d, %d", 1729 port_id, ret); 1730 return ret; 1731 } 1732 } 1733 1734 return 0; 1735 } 1736 1737 int32_t 1738 eh_devs_uninit(struct eh_conf *conf) 1739 { 1740 struct eventmode_conf *em_conf; 1741 int ret, i, j; 1742 uint16_t id; 1743 1744 if (conf == NULL) { 1745 EH_LOG_ERR("Invalid event helper configuration"); 1746 return -EINVAL; 1747 } 1748 1749 if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT) 1750 return 0; 1751 1752 if (conf->mode_params == NULL) { 1753 EH_LOG_ERR("Invalid event mode parameters"); 1754 return -EINVAL; 1755 } 1756 1757 /* Get eventmode conf */ 1758 em_conf = conf->mode_params; 1759 1760 /* Stop and release rx adapters */ 1761 for (i = 0; i < em_conf->nb_rx_adapter; i++) { 1762 1763 id = em_conf->rx_adapter[i].adapter_id; 1764 ret = rte_event_eth_rx_adapter_stop(id); 1765 if (ret < 0) { 1766 EH_LOG_ERR("Failed to stop rx adapter %d", ret); 1767 return ret; 1768 } 1769 1770 for (j = 0; j < em_conf->rx_adapter[i].nb_connections; j++) { 1771 1772 ret = rte_event_eth_rx_adapter_queue_del(id, 1773 em_conf->rx_adapter[i].conn[j].ethdev_id, -1); 1774 if (ret < 0) { 1775 EH_LOG_ERR( 1776 "Failed to remove rx adapter queues %d", 1777 ret); 1778 return ret; 1779 } 1780 } 1781 1782 ret = rte_event_eth_rx_adapter_free(id); 1783 if (ret < 0) { 1784 EH_LOG_ERR("Failed to free rx adapter %d", ret); 1785 return ret; 1786 } 1787 } 1788 1789 /* Stop and release event devices */ 1790 for (i = 0; i < em_conf->nb_eventdev; i++) { 1791 1792 id = em_conf->eventdev_config[i].eventdev_id; 1793 rte_event_dev_stop(id); 1794 1795 ret = rte_event_dev_close(id); 1796 if (ret < 0) { 1797 EH_LOG_ERR("Failed to close event dev %d, %d", id, ret); 1798 return ret; 1799 } 1800 } 1801 1802 /* Stop and release tx adapters */ 1803 for (i = 0; i < em_conf->nb_tx_adapter; i++) { 1804 1805 id = em_conf->tx_adapter[i].adapter_id; 1806 ret = rte_event_eth_tx_adapter_stop(id); 1807 if (ret < 0) { 1808 EH_LOG_ERR("Failed to stop tx adapter %d", ret); 1809 return ret; 1810 } 1811 1812 for (j = 0; j < em_conf->tx_adapter[i].nb_connections; j++) { 1813 1814 ret = rte_event_eth_tx_adapter_queue_del(id, 1815 em_conf->tx_adapter[i].conn[j].ethdev_id, -1); 1816 if (ret < 0) { 1817 EH_LOG_ERR( 1818 "Failed to remove tx adapter queues %d", 1819 ret); 1820 return ret; 1821 } 1822 } 1823 1824 ret = rte_event_eth_tx_adapter_free(id); 1825 if (ret < 0) { 1826 EH_LOG_ERR("Failed to free tx adapter %d", ret); 1827 return ret; 1828 } 1829 } 1830 1831 return 0; 1832 } 1833 1834 void 1835 eh_launch_worker(struct eh_conf *conf, struct eh_app_worker_params *app_wrkr, 1836 uint8_t nb_wrkr_param) 1837 { 1838 struct eh_app_worker_params *match_wrkr; 1839 struct eh_event_link_info *links = NULL; 1840 struct eventmode_conf *em_conf; 1841 uint32_t lcore_id; 1842 uint8_t nb_links; 1843 1844 if (conf == NULL) { 1845 EH_LOG_ERR("Invalid event helper configuration"); 1846 return; 1847 } 1848 1849 if (conf->mode_params == NULL) { 1850 EH_LOG_ERR("Invalid event mode parameters"); 1851 return; 1852 } 1853 1854 /* Get eventmode conf */ 1855 em_conf = conf->mode_params; 1856 1857 /* Get core ID */ 1858 lcore_id = rte_lcore_id(); 1859 1860 /* Check if this is eth core */ 1861 if (rte_bitmap_get(em_conf->eth_core_mask, lcore_id)) { 1862 eh_start_worker_eth_core(em_conf, lcore_id); 1863 return; 1864 } 1865 1866 if (app_wrkr == NULL || nb_wrkr_param == 0) { 1867 EH_LOG_ERR("Invalid args"); 1868 return; 1869 } 1870 1871 /* 1872 * This is a regular worker thread. The application registers 1873 * multiple workers with various capabilities. Run worker 1874 * based on the selected capabilities of the event 1875 * device configured. 1876 */ 1877 1878 /* Get the first matching worker for the event device */ 1879 match_wrkr = eh_find_worker(lcore_id, conf, app_wrkr, nb_wrkr_param); 1880 if (match_wrkr == NULL) { 1881 EH_LOG_ERR("Failed to match worker registered for lcore %d", 1882 lcore_id); 1883 goto clean_and_exit; 1884 } 1885 1886 /* Verify sanity of the matched worker */ 1887 if (eh_verify_match_worker(match_wrkr) != 1) { 1888 EH_LOG_ERR("Failed to validate the matched worker"); 1889 goto clean_and_exit; 1890 } 1891 1892 /* Get worker links */ 1893 nb_links = eh_get_event_lcore_links(lcore_id, conf, &links); 1894 1895 /* Launch the worker thread */ 1896 match_wrkr->worker_thread(links, nb_links); 1897 1898 /* Free links info memory */ 1899 free(links); 1900 1901 clean_and_exit: 1902 1903 /* Flag eth_cores to stop, if started */ 1904 eh_stop_worker_eth_core(); 1905 } 1906 1907 uint8_t 1908 eh_get_tx_queue(struct eh_conf *conf, uint8_t eventdev_id) 1909 { 1910 struct eventdev_params *eventdev_config; 1911 struct eventmode_conf *em_conf; 1912 1913 if (conf == NULL) { 1914 EH_LOG_ERR("Invalid event helper configuration"); 1915 return -EINVAL; 1916 } 1917 1918 if (conf->mode_params == NULL) { 1919 EH_LOG_ERR("Invalid event mode parameters"); 1920 return -EINVAL; 1921 } 1922 1923 /* Get eventmode conf */ 1924 em_conf = conf->mode_params; 1925 1926 /* Get event device conf */ 1927 eventdev_config = eh_get_eventdev_params(em_conf, eventdev_id); 1928 1929 if (eventdev_config == NULL) { 1930 EH_LOG_ERR("Failed to read eventdev config"); 1931 return -EINVAL; 1932 } 1933 1934 /* 1935 * The last queue is reserved to be used as atomic queue for the 1936 * last stage (eth packet tx stage) 1937 */ 1938 return eventdev_config->nb_eventqueue - 1; 1939 } 1940