#include <stdlib.h>
#include <stdbool.h>
#include "event_helper.h"
#include "ipsec-secgw.h"
#define DEFAULT_VECTOR_SIZE 16
#define DEFAULT_VECTOR_TMO 102400
#define INVALID_EV_QUEUE_ID -1
static volatile bool eth_core_running;
static int
eh_get_enabled_cores(
struct rte_bitmap *eth_core_mask)
{
int i, count = 0;
count++;
}
}
return count;
}
static inline unsigned int
eh_get_next_eth_core(struct eventmode_conf *em_conf)
{
static unsigned int prev_core = -1;
unsigned int next_core;
if (eh_get_enabled_cores(em_conf->eth_core_mask) == 0) {
EH_LOG_ERR("No enabled eth core found");
return RTE_MAX_LCORE;
}
do {
if (next_core == RTE_MAX_LCORE)
return next_core;
prev_core = next_core;
return next_core;
}
static inline unsigned int
eh_get_next_active_core(struct eventmode_conf *em_conf, unsigned int prev_core)
{
unsigned int next_core;
do {
if (next_core == RTE_MAX_LCORE)
return next_core;
prev_core = next_core;
return next_core;
}
static struct eventdev_params *
eh_get_eventdev_params(struct eventmode_conf *em_conf, uint8_t eventdev_id)
{
int i;
for (i = 0; i < em_conf->nb_eventdev; i++) {
if (em_conf->eventdev_config[i].eventdev_id == eventdev_id)
break;
}
if (i == em_conf->nb_eventdev)
return NULL;
return &(em_conf->eventdev_config[i]);
}
static inline bool
eh_dev_has_rx_internal_port(uint8_t eventdev_id)
{
bool flag = true;
int j, ret;
uint32_t caps = 0;
if (ret < 0)
return false;
flag = false;
}
return flag;
}
static inline bool
eh_dev_has_tx_internal_port(uint8_t eventdev_id)
{
bool flag = true;
int j, ret;
uint32_t caps = 0;
if (ret < 0)
return false;
flag = false;
}
return flag;
}
static inline bool
eh_dev_has_burst_mode(uint8_t dev_id)
{
true : false;
}
static int
eh_set_nb_eventdev(struct eventmode_conf *em_conf)
{
struct eventdev_params *eventdev_config;
int nb_eventdev;
if (nb_eventdev == 0) {
EH_LOG_ERR("No event devices detected");
return -EINVAL;
}
if (nb_eventdev != 1) {
EH_LOG_ERR("Event mode does not support multiple event devices. "
"Please provide only one event device.");
return -EINVAL;
}
eventdev_config = &(em_conf->eventdev_config[0]);
eventdev_config->eventdev_id = 0;
em_conf->nb_eventdev = 1;
return 0;
}
static int
eh_set_default_conf_eventdev(struct eventmode_conf *em_conf)
{
int lcore_count, nb_eth_dev, ret;
struct eventdev_params *eventdev_config;
if (nb_eth_dev == 0) {
EH_LOG_ERR("No eth devices detected");
return -EINVAL;
}
if (ret < 0) {
EH_LOG_ERR("Failed to read event device info %d", ret);
return ret;
}
EH_LOG_ERR("Not enough event ports available");
return -EINVAL;
}
eventdev_config = &(em_conf->eventdev_config[0]);
eventdev_config->nb_eventqueue = nb_eth_dev;
eventdev_config->tx_queue_id = INVALID_EV_QUEUE_ID;
if (eventdev_config->all_internal_ports) {
EH_LOG_ERR("Not enough event queues available");
return -EINVAL;
}
eventdev_config->tx_queue_id =
eventdev_config->nb_eventqueue++;
}
eventdev_config->ev_cpt_queue_id = INVALID_EV_QUEUE_ID;
if (em_conf->enable_event_crypto_adapter) {
EH_LOG_ERR("Not enough event queues available");
return -EINVAL;
}
eventdev_config->ev_cpt_queue_id =
eventdev_config->nb_eventqueue++;
}
if (eventdev_config->nb_eventport > lcore_count) {
eventdev_config->nb_eventport = lcore_count;
}
return 0;
}
static void
eh_do_capability_check(struct eventmode_conf *em_conf)
{
struct eventdev_params *eventdev_config;
int all_internal_ports = 1;
uint32_t eventdev_id;
int i;
for (i = 0; i < em_conf->nb_eventdev; i++) {
eventdev_config = &(em_conf->eventdev_config[i]);
eventdev_id = eventdev_config->eventdev_id;
if (eh_dev_has_rx_internal_port(eventdev_id) &&
eh_dev_has_tx_internal_port(eventdev_id)) {
eventdev_config->all_internal_ports = 1;
} else {
all_internal_ports = 0;
}
}
if (all_internal_ports)
}
static int
eh_set_default_conf_link(struct eventmode_conf *em_conf)
{
struct eventdev_params *eventdev_config;
struct eh_event_link_info *link;
unsigned int lcore_id = -1;
int i, link_index;
em_conf->ext_params.all_ev_queue_to_ev_port = 1;
eventdev_config = &(em_conf->eventdev_config[0]);
for (i = 0; i < eventdev_config->nb_eventport; i++) {
lcore_id = eh_get_next_active_core(em_conf,
lcore_id);
if (lcore_id == RTE_MAX_LCORE) {
return 0;
}
link_index = em_conf->nb_link;
link = &(em_conf->link[link_index]);
link->eventdev_id = eventdev_config->eventdev_id;
link->event_port_id = i;
link->lcore_id = lcore_id;
em_conf->nb_link++;
}
return 0;
}
static int
eh_set_default_conf_rx_adapter(struct eventmode_conf *em_conf)
{
struct rx_adapter_connection_info *conn;
struct eventdev_params *eventdev_config;
struct rx_adapter_conf *adapter;
bool rx_internal_port = true;
bool single_ev_queue = false;
int nb_eventqueue;
uint32_t caps = 0;
int eventdev_id;
int nb_eth_dev;
int adapter_id;
int conn_id;
int ret;
int i;
if (em_conf->nb_eventdev == 0) {
EH_LOG_ERR("No event devs registered");
return -EINVAL;
}
eventdev_config = &(em_conf->eventdev_config[0]);
eventdev_id = eventdev_config->eventdev_id;
adapter_id = 0;
adapter = &(em_conf->rx_adapter[adapter_id]);
adapter->eventdev_id = eventdev_id;
adapter->adapter_id = adapter_id;
nb_eventqueue = eventdev_config->all_internal_ports ?
eventdev_config->nb_eventqueue :
eventdev_config->nb_eventqueue - 1;
if (em_conf->enable_event_crypto_adapter)
nb_eventqueue--;
if (nb_eth_dev > nb_eventqueue)
single_ev_queue = true;
for (i = 0; i < nb_eth_dev; i++) {
if ((em_conf->eth_portmask & (1 << i)) == 0)
continue;
conn_id = adapter->nb_connections;
conn = &(adapter->conn[conn_id]);
conn->ethdev_id = i;
conn->eventq_id = single_ev_queue ? 0 : i;
conn->ethdev_rx_qid = -1;
if (ret < 0) {
EH_LOG_ERR("Failed to get event device %d eth rx adapter"
" capabilities for port %d", eventdev_id, i);
return ret;
}
rx_internal_port = false;
adapter->nb_connections++;
}
if (rx_internal_port) {
adapter->rx_core_id = -1;
} else {
adapter->rx_core_id = eh_get_next_eth_core(em_conf);
}
em_conf->nb_rx_adapter = 1;
return 0;
}
static int
eh_set_default_conf_tx_adapter(struct eventmode_conf *em_conf)
{
struct tx_adapter_connection_info *conn;
struct eventdev_params *eventdev_config;
struct tx_adapter_conf *tx_adapter;
bool tx_internal_port = true;
uint32_t caps = 0;
int eventdev_id;
int adapter_id;
int nb_eth_dev;
int conn_id;
int ret;
int i;
if (em_conf->nb_eventdev == 0) {
EH_LOG_ERR("No event devs registered");
return -EINVAL;
}
eventdev_config = &(em_conf->eventdev_config[0]);
eventdev_id = eventdev_config->eventdev_id;
adapter_id = 0;
tx_adapter = &(em_conf->tx_adapter[adapter_id]);
tx_adapter->eventdev_id = eventdev_id;
tx_adapter->adapter_id = adapter_id;
for (i = 0; i < nb_eth_dev; i++) {
if ((em_conf->eth_portmask & (1 << i)) == 0)
continue;
conn_id = tx_adapter->nb_connections;
conn = &(tx_adapter->conn[conn_id]);
conn->ethdev_id = i;
conn->ethdev_tx_qid = -1;
if (ret < 0) {
EH_LOG_ERR("Failed to get event device %d eth tx adapter"
" capabilities for port %d", eventdev_id, i);
return ret;
}
tx_internal_port = false;
tx_adapter->nb_connections++;
}
if (tx_internal_port) {
tx_adapter->tx_core_id = -1;
} else {
tx_adapter->tx_core_id = eh_get_next_eth_core(em_conf);
tx_adapter->tx_ev_queue = eventdev_config->nb_eventqueue - 1;
}
em_conf->nb_tx_adapter = 1;
return 0;
}
static int
eh_validate_conf(struct eventmode_conf *em_conf)
{
int ret;
if (em_conf->nb_eventdev == 0) {
ret = eh_set_nb_eventdev(em_conf);
if (ret != 0)
return ret;
eh_do_capability_check(em_conf);
ret = eh_set_default_conf_eventdev(em_conf);
if (ret != 0)
return ret;
} else {
eh_do_capability_check(em_conf);
}
if (em_conf->nb_link == 0) {
ret = eh_set_default_conf_link(em_conf);
if (ret != 0)
return ret;
}
if (em_conf->nb_rx_adapter == 0) {
ret = eh_set_default_conf_rx_adapter(em_conf);
if (ret != 0)
return ret;
}
if (em_conf->nb_tx_adapter == 0) {
ret = eh_set_default_conf_tx_adapter(em_conf);
if (ret != 0)
return ret;
}
return 0;
}
static int
eh_initialize_eventdev(struct eventmode_conf *em_conf)
{
struct eventdev_params *eventdev_config;
int nb_eventdev = em_conf->nb_eventdev;
struct eh_event_link_info *link;
uint8_t *queue = NULL;
uint8_t eventdev_id;
int nb_eventqueue;
int ret, j;
uint8_t i;
for (i = 0; i < nb_eventdev; i++) {
eventdev_config = &(em_conf->eventdev_config[i]);
eventdev_id = eventdev_config->eventdev_id;
nb_eventqueue = eventdev_config->nb_eventqueue;
memset(&evdev_default_conf, 0,
if (ret < 0) {
EH_LOG_ERR(
"Error in getting event device info[devID:%d]",
eventdev_id);
return ret;
}
eventdev_config->nb_eventport;
if (ret < 0) {
EH_LOG_ERR("Error in configuring event device");
return ret;
}
for (j = 0; j < nb_eventqueue; j++) {
memset(&eventq_conf, 0,
eventdev_config->ev_queue_mode;
if (j == eventdev_config->tx_queue_id) {
} else {
em_conf->ext_params.sched_type;
}
if (j == eventdev_config->ev_cpt_queue_id) {
} else {
}
&eventq_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to setup event queue %d",
ret);
return ret;
}
}
for (j = 0; j < eventdev_config->nb_eventport; j++) {
if (ret < 0) {
EH_LOG_ERR("Failed to setup event port %d",
ret);
return ret;
}
}
}
for (j = 0; j < em_conf->nb_link; j++) {
link = &(em_conf->link[j]);
eventdev_id = link->eventdev_id;
if (em_conf->ext_params.all_ev_queue_to_ev_port)
queue = NULL;
else
queue = &(link->eventq_id);
queue, NULL, 1);
if (ret < 0) {
EH_LOG_ERR("Failed to link event port %d", ret);
return ret;
}
}
return 0;
}
static int
eh_start_eventdev(struct eventmode_conf *em_conf)
{
struct eventdev_params *eventdev_config;
int nb_eventdev = em_conf->nb_eventdev;
int i, ret;
for (i = 0; i < nb_eventdev; i++) {
eventdev_config = &(em_conf->eventdev_config[i]);
if (ret < 0) {
EH_LOG_ERR("Failed to start event device %d, %d",
i, ret);
return ret;
}
}
return 0;
}
static int
eh_initialize_crypto_adapter(struct eventmode_conf *em_conf)
{
struct eventdev_params *eventdev_config;
char mp_name[RTE_MEMPOOL_NAMESIZE];
const uint8_t nb_qp_per_cdev = 1;
uint8_t eventdev_id, cdev_id, n;
uint32_t cap, nb_elem;
int ret, socket_id;
if (!em_conf->enable_event_crypto_adapter)
return 0;
RTE_ASSERT(em_conf->nb_eventdev == 1);
eventdev_config = &(em_conf->eventdev_config[0]);
eventdev_id = eventdev_config->eventdev_id;
for (cdev_id = 0; cdev_id != n; cdev_id++) {
if (ret < 0) {
EH_LOG_ERR("Failed to get event device's crypto capabilities %d", ret);
return ret;
}
EH_LOG_ERR("Event crypto adapter does not support forward mode!");
return -EINVAL;
}
if (ret < 0) {
EH_LOG_ERR("Failed to get event dev info %d", ret);
return ret;
}
if (ret < 0) {
EH_LOG_ERR("Failed to create event crypto adapter %d", ret);
return ret;
}
memset(&queue_conf, 0, sizeof(queue_conf));
(em_conf->ext_params.event_vector)) {
queue_conf.
vector_sz = em_conf->ext_params.vector_size;
nb_elem = (qp_desc_nb / queue_conf.
vector_sz) + 1;
nb_elem *= nb_qp_per_cdev;
socket_id = rte_cryptodev_socket_id(cdev_id);
snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
"QP_VEC_%u_%u", socket_id, cdev_id);
mp_name, nb_elem, 0,
EH_LOG_ERR("failed to create event vector pool");
return -ENOMEM;
}
}
-1,
&queue_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to add queue pairs to event crypto adapter %d", ret);
return ret;
}
}
return 0;
}
static int
eh_start_crypto_adapter(struct eventmode_conf *em_conf)
{
uint8_t cdev_id, n;
int ret;
if (!em_conf->enable_event_crypto_adapter)
return 0;
for (cdev_id = 0; cdev_id != n; cdev_id++) {
if (ret < 0) {
EH_LOG_ERR("Failed to start event crypto device %d (%d)",
cdev_id, ret);
return ret;
}
}
return 0;
}
static int
eh_stop_crypto_adapter(struct eventmode_conf *em_conf)
{
uint8_t cdev_id, n;
int ret;
if (!em_conf->enable_event_crypto_adapter)
return 0;
for (cdev_id = 0; cdev_id != n; cdev_id++) {
if (ret < 0) {
EH_LOG_ERR("Failed to stop event crypto device %d (%d)",
cdev_id, ret);
return ret;
}
}
return 0;
}
static int
eh_event_vector_limits_validate(struct eventmode_conf *em_conf,
uint8_t ev_dev_id, uint8_t ethdev_id)
{
uint16_t vector_size = em_conf->ext_params.vector_size;
int ret;
&limits);
if (ret) {
EH_LOG_ERR("failed to get vector limits");
return ret;
}
if (vector_size < limits.min_sz || vector_size > limits.
max_sz) {
EH_LOG_ERR("Vector size [%d] not within limits min[%d] max[%d]",
return -EINVAL;
}
EH_LOG_ERR("Vector size [%d] not power of 2", vector_size);
return -EINVAL;
}
EH_LOG_ERR("Vector timeout [%" PRIu64
"] not within limits max[%" PRIu64
"] min[%" PRIu64 "]",
em_conf->vector_tmo_ns,
return -EINVAL;
}
return 0;
}
static int
eh_rx_adapter_configure(struct eventmode_conf *em_conf,
struct rx_adapter_conf *adapter)
{
struct rx_adapter_connection_info *conn;
uint32_t service_id, socket_id, nb_elem;
int ret, portid, nb_ports = 0;
uint8_t eventdev_id;
int j;
eventdev_id = adapter->eventdev_id;
if (ret < 0) {
EH_LOG_ERR("Failed to get event dev info %d", ret);
return ret;
}
if ((em_conf->eth_portmask & (1 << portid)))
nb_ports++;
if (em_conf->ext_params.event_vector) {
if (em_conf->vector_pool_sz) {
nb_elem = em_conf->vector_pool_sz;
} else {
nb_elem = (nb_bufs_in_pool /
em_conf->ext_params.vector_size) + 1;
if (per_port_pool)
nb_elem = nb_ports * nb_elem;
}
"vector_pool", nb_elem, 32,
em_conf->ext_params.vector_size, socket_id);
if (vector_pool == NULL) {
EH_LOG_ERR("failed to create event vector pool");
return -ENOMEM;
}
}
adapter->eventdev_id, &port_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to create rx adapter %d", ret);
return ret;
}
for (j = 0; j < adapter->nb_connections; j++) {
conn = &(adapter->conn[j]);
if (em_conf->ext_params.event_vector) {
ret = eh_event_vector_limits_validate(em_conf,
eventdev_id,
conn->ethdev_id);
if (ret)
return ret;
queue_conf.
vector_sz = em_conf->ext_params.vector_size;
}
conn->ethdev_id, conn->ethdev_rx_qid,
&queue_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to add eth queue to rx adapter %d",
ret);
return ret;
}
}
&service_id);
if (ret != -ESRCH && ret < 0) {
EH_LOG_ERR("Failed to get service id used by rx adapter %d",
ret);
return ret;
}
if (ret < 0) {
EH_LOG_ERR("Failed to start rx adapter %d", ret);
return ret;
}
return 0;
}
static int
eh_initialize_rx_adapter(struct eventmode_conf *em_conf)
{
struct rx_adapter_conf *adapter;
int i, ret;
for (i = 0; i < em_conf->nb_rx_adapter; i++) {
adapter = &(em_conf->rx_adapter[i]);
ret = eh_rx_adapter_configure(em_conf, adapter);
if (ret < 0) {
EH_LOG_ERR("Failed to configure rx adapter %d", ret);
return ret;
}
}
return 0;
}
static int32_t
eh_start_worker_eth_core(struct eventmode_conf *conf, uint32_t lcore_id)
{
uint32_t service_id[EVENT_MODE_MAX_ADAPTERS_PER_RX_CORE];
struct rx_adapter_conf *rx_adapter;
struct tx_adapter_conf *tx_adapter;
int service_count = 0;
int adapter_id;
int32_t ret;
int i;
EH_LOG_INFO("Entering eth_core processing on lcore %u", lcore_id);
for (i = 0; i < conf->nb_rx_adapter; i++) {
if (service_count > EVENT_MODE_MAX_ADAPTERS_PER_RX_CORE) {
EH_LOG_ERR(
"Exceeded the max allowed adapters per rx core");
break;
}
rx_adapter = &(conf->rx_adapter[i]);
if (rx_adapter->rx_core_id != lcore_id)
continue;
adapter_id = rx_adapter->adapter_id;
&(service_id[service_count]));
if (ret != -ESRCH && ret < 0) {
EH_LOG_ERR(
"Failed to get service id used by rx adapter");
return ret;
}
service_count++;
}
for (i = 0; i < conf->nb_tx_adapter; i++) {
if (service_count > EVENT_MODE_MAX_ADAPTERS_PER_TX_CORE) {
EH_LOG_ERR(
"Exceeded the max allowed adapters per tx core");
break;
}
tx_adapter = &conf->tx_adapter[i];
if (tx_adapter->tx_core_id != lcore_id)
continue;
adapter_id = tx_adapter->adapter_id;
&(service_id[service_count]));
if (ret != -ESRCH && ret < 0) {
EH_LOG_ERR(
"Failed to get service id used by tx adapter");
return ret;
}
service_count++;
}
eth_core_running = true;
while (eth_core_running) {
for (i = 0; i < service_count; i++) {
}
}
return 0;
}
static int32_t
eh_stop_worker_eth_core(void)
{
if (eth_core_running) {
EH_LOG_INFO("Stopping eth cores");
eth_core_running = false;
}
return 0;
}
static struct eh_app_worker_params *
eh_find_worker(uint32_t lcore_id, struct eh_conf *conf,
struct eh_app_worker_params *app_wrkrs, uint8_t nb_wrkr_param)
{
struct eh_app_worker_params curr_conf = { {{0} }, NULL};
struct eh_event_link_info *link = NULL;
struct eh_app_worker_params *tmp_wrkr;
struct eventmode_conf *em_conf;
uint8_t eventdev_id;
int i;
em_conf = conf->mode_params;
for (i = 0; i < em_conf->nb_link; i++) {
link = &(em_conf->link[i]);
if (link->lcore_id == lcore_id)
break;
}
if (link == NULL) {
EH_LOG_ERR("No valid link found for lcore %d", lcore_id);
return NULL;
}
eventdev_id = link->eventdev_id;
if (eh_dev_has_tx_internal_port(eventdev_id))
curr_conf.cap.tx_internal_port = EH_TX_TYPE_INTERNAL_PORT;
else
curr_conf.cap.tx_internal_port = EH_TX_TYPE_NO_INTERNAL_PORT;
if (eh_dev_has_burst_mode(eventdev_id))
curr_conf.cap.burst = EH_RX_TYPE_BURST;
else
curr_conf.cap.burst = EH_RX_TYPE_NON_BURST;
curr_conf.cap.ipsec_mode = conf->ipsec_mode;
tmp_wrkr = app_wrkrs;
for (i = 0; i < nb_wrkr_param; i++, tmp_wrkr++) {
if (tmp_wrkr->cap.u64 != curr_conf.cap.u64)
continue;
return tmp_wrkr;
}
return NULL;
}
static int
eh_verify_match_worker(struct eh_app_worker_params *match_wrkr)
{
if (match_wrkr->worker_thread == NULL) {
EH_LOG_ERR("No worker registered");
return 0;
}
return 1;
}
static uint8_t
eh_get_event_lcore_links(uint32_t lcore_id, struct eh_conf *conf,
struct eh_event_link_info **links)
{
struct eh_event_link_info *link_cache;
struct eventmode_conf *em_conf = NULL;
struct eh_event_link_info *link;
uint8_t lcore_nb_link = 0;
size_t single_link_size;
size_t cache_size;
int index = 0;
int i;
if (conf == NULL || links == NULL) {
EH_LOG_ERR("Invalid args");
return -EINVAL;
}
em_conf = conf->mode_params;
if (em_conf == NULL) {
EH_LOG_ERR("Invalid event mode parameters");
return -EINVAL;
}
for (i = 0; i < em_conf->nb_link; i++) {
link = &(em_conf->link[i]);
if (link->lcore_id == lcore_id) {
lcore_nb_link++;
}
}
single_link_size = sizeof(struct eh_event_link_info);
cache_size = lcore_nb_link * sizeof(struct eh_event_link_info);
link_cache = calloc(1, cache_size);
for (i = 0; i < em_conf->nb_link; i++) {
link = &(em_conf->link[i]);
if (link->lcore_id == lcore_id) {
memcpy(&link_cache[index], link, single_link_size);
index++;
}
}
*links = link_cache;
return lcore_nb_link;
}
static int
eh_tx_adapter_configure(struct eventmode_conf *em_conf,
struct tx_adapter_conf *adapter)
{
struct tx_adapter_connection_info *conn;
struct eventdev_params *eventdev_config;
uint8_t tx_port_id = 0;
uint8_t eventdev_id;
uint32_t service_id;
int ret, j;
eventdev_id = adapter->eventdev_id;
eventdev_config = eh_get_eventdev_params(em_conf, eventdev_id);
if (ret < 0) {
EH_LOG_ERR("Failed to get event dev info %d", ret);
return ret;
}
adapter->eventdev_id, &port_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to create tx adapter %d", ret);
return ret;
}
for (j = 0; j < adapter->nb_connections; j++) {
conn = &(adapter->conn[j]);
conn->ethdev_id, conn->ethdev_tx_qid);
if (ret < 0) {
EH_LOG_ERR("Failed to add eth queue to tx adapter %d",
ret);
return ret;
}
}
if (adapter->tx_core_id == (uint32_t) (-1)) {
goto skip_tx_queue_port_setup;
}
adapter->adapter_id, &tx_port_id);
if (ret) {
EH_LOG_ERR("Failed to get tx adapter port id %d", ret);
return ret;
}
for (j = 0; j < eventdev_config->nb_eventport; j++) {
&(adapter->tx_ev_queue), 1);
}
&(adapter->tx_ev_queue), NULL, 1);
if (ret != 1) {
EH_LOG_ERR("Failed to link event queue to port");
return ret;
}
&service_id);
if (ret != -ESRCH && ret < 0) {
EH_LOG_ERR("Failed to get service id used by tx adapter %d",
ret);
return ret;
}
skip_tx_queue_port_setup:
if (ret < 0) {
EH_LOG_ERR("Failed to start tx adapter %d", ret);
return ret;
}
return 0;
}
static int
eh_initialize_tx_adapter(struct eventmode_conf *em_conf)
{
struct tx_adapter_conf *adapter;
int i, ret;
for (i = 0; i < em_conf->nb_tx_adapter; i++) {
adapter = &(em_conf->tx_adapter[i]);
ret = eh_tx_adapter_configure(em_conf, adapter);
if (ret < 0) {
EH_LOG_ERR("Failed to configure tx adapter %d", ret);
return ret;
}
}
return 0;
}
static void
eh_display_operating_mode(struct eventmode_conf *em_conf)
{
char sched_types[][32] = {
"RTE_SCHED_TYPE_ORDERED",
"RTE_SCHED_TYPE_ATOMIC",
"RTE_SCHED_TYPE_PARALLEL",
};
EH_LOG_INFO("Operating mode:");
EH_LOG_INFO("\tScheduling type: \t%s",
sched_types[em_conf->ext_params.sched_type]);
EH_LOG_INFO("");
}
static void
eh_display_event_dev_conf(struct eventmode_conf *em_conf)
{
char queue_mode[][32] = {
"",
"ATQ (ALL TYPE QUEUE)",
"SINGLE LINK",
};
char print_buf[256] = { 0 };
int i;
EH_LOG_INFO("Event Device Configuration:");
for (i = 0; i < em_conf->nb_eventdev; i++) {
sprintf(print_buf,
"\tDev ID: %-2d \tQueues: %-2d \tPorts: %-2d",
em_conf->eventdev_config[i].eventdev_id,
em_conf->eventdev_config[i].nb_eventqueue,
em_conf->eventdev_config[i].nb_eventport);
sprintf(print_buf + strlen(print_buf),
"\tQueue mode: %s",
queue_mode[em_conf->eventdev_config[i].ev_queue_mode]);
EH_LOG_INFO("%s", print_buf);
}
EH_LOG_INFO("");
}
static void
eh_display_rx_adapter_conf(struct eventmode_conf *em_conf)
{
int nb_rx_adapter = em_conf->nb_rx_adapter;
struct rx_adapter_connection_info *conn;
struct rx_adapter_conf *adapter;
char print_buf[256] = { 0 };
int i, j;
EH_LOG_INFO("Rx adapters configured: %d", nb_rx_adapter);
for (i = 0; i < nb_rx_adapter; i++) {
adapter = &(em_conf->rx_adapter[i]);
sprintf(print_buf,
"\tRx adapter ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d",
adapter->adapter_id,
adapter->nb_connections,
adapter->eventdev_id);
if (adapter->rx_core_id == (uint32_t)-1)
sprintf(print_buf + strlen(print_buf),
"\tRx core: %-2s", "[INTERNAL PORT]");
else if (adapter->rx_core_id == RTE_MAX_LCORE)
sprintf(print_buf + strlen(print_buf),
"\tRx core: %-2s", "[NONE]");
else
sprintf(print_buf + strlen(print_buf),
"\tRx core: %-2d", adapter->rx_core_id);
EH_LOG_INFO("%s", print_buf);
for (j = 0; j < adapter->nb_connections; j++) {
conn = &(adapter->conn[j]);
sprintf(print_buf,
"\t\tEthdev ID: %-2d", conn->ethdev_id);
if (conn->ethdev_rx_qid == -1)
sprintf(print_buf + strlen(print_buf),
"\tEth rx queue: %-2s", "ALL");
else
sprintf(print_buf + strlen(print_buf),
"\tEth rx queue: %-2d",
conn->ethdev_rx_qid);
sprintf(print_buf + strlen(print_buf),
"\tEvent queue: %-2d", conn->eventq_id);
EH_LOG_INFO("%s", print_buf);
}
}
EH_LOG_INFO("");
}
static void
eh_display_tx_adapter_conf(struct eventmode_conf *em_conf)
{
int nb_tx_adapter = em_conf->nb_tx_adapter;
struct tx_adapter_connection_info *conn;
struct tx_adapter_conf *adapter;
char print_buf[256] = { 0 };
int i, j;
EH_LOG_INFO("Tx adapters configured: %d", nb_tx_adapter);
for (i = 0; i < nb_tx_adapter; i++) {
adapter = &(em_conf->tx_adapter[i]);
sprintf(print_buf,
"\tTx adapter ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d",
adapter->adapter_id,
adapter->nb_connections,
adapter->eventdev_id);
if (adapter->tx_core_id == (uint32_t)-1)
sprintf(print_buf + strlen(print_buf),
"\tTx core: %-2s", "[INTERNAL PORT]");
else if (adapter->tx_core_id == RTE_MAX_LCORE)
sprintf(print_buf + strlen(print_buf),
"\tTx core: %-2s", "[NONE]");
else
sprintf(print_buf + strlen(print_buf),
"\tTx core: %-2d,\tInput event queue: %-2d",
adapter->tx_core_id, adapter->tx_ev_queue);
EH_LOG_INFO("%s", print_buf);
for (j = 0; j < adapter->nb_connections; j++) {
conn = &(adapter->conn[j]);
sprintf(print_buf,
"\t\tEthdev ID: %-2d", conn->ethdev_id);
if (conn->ethdev_tx_qid == -1)
sprintf(print_buf + strlen(print_buf),
"\tEth tx queue: %-2s", "ALL");
else
sprintf(print_buf + strlen(print_buf),
"\tEth tx queue: %-2d",
conn->ethdev_tx_qid);
EH_LOG_INFO("%s", print_buf);
}
}
EH_LOG_INFO("");
}
static void
eh_display_link_conf(struct eventmode_conf *em_conf)
{
struct eh_event_link_info *link;
char print_buf[256] = { 0 };
int i;
EH_LOG_INFO("Links configured: %d", em_conf->nb_link);
for (i = 0; i < em_conf->nb_link; i++) {
link = &(em_conf->link[i]);
sprintf(print_buf,
"\tEvent dev ID: %-2d\tEvent port: %-2d",
link->eventdev_id,
link->event_port_id);
if (em_conf->ext_params.all_ev_queue_to_ev_port)
sprintf(print_buf + strlen(print_buf),
"Event queue: %-2s\t", "ALL");
else
sprintf(print_buf + strlen(print_buf),
"Event queue: %-2d\t", link->eventq_id);
sprintf(print_buf + strlen(print_buf),
"Lcore: %-2d", link->lcore_id);
EH_LOG_INFO("%s", print_buf);
}
EH_LOG_INFO("");
}
struct eh_conf *
eh_conf_init(void)
{
struct eventmode_conf *em_conf = NULL;
struct eh_conf *conf = NULL;
unsigned int eth_core_id;
void *bitmap = NULL;
uint32_t nb_bytes;
conf = calloc(1, sizeof(struct eh_conf));
if (conf == NULL) {
EH_LOG_ERR("Failed to allocate memory for eventmode helper "
"config");
return NULL;
}
conf->mode = EH_PKT_TRANSFER_MODE_POLL;
conf->ipsec_mode = EH_IPSEC_MODE_TYPE_APP;
conf->eth_portmask = -1;
conf->mode_params = calloc(1, sizeof(struct eventmode_conf));
if (conf->mode_params == NULL) {
EH_LOG_ERR("Failed to allocate memory for event mode params");
goto free_conf;
}
em_conf = conf->mode_params;
if (!nb_bytes) {
EH_LOG_ERR("Failed to get bitmap footprint");
goto free_em_conf;
}
bitmap =
rte_zmalloc(
"event-helper-ethcore-bitmap", nb_bytes,
RTE_CACHE_LINE_SIZE);
if (!bitmap) {
EH_LOG_ERR("Failed to allocate memory for eth cores bitmap\n");
goto free_em_conf;
}
nb_bytes);
if (!em_conf->eth_core_mask) {
EH_LOG_ERR("Failed to initialize bitmap");
goto free_bitmap;
}
em_conf->ext_params.sched_type = SCHED_TYPE_NOT_SET;
1,
0 );
1,
0 );
em_conf->ext_params.vector_size = DEFAULT_VECTOR_SIZE;
em_conf->vector_tmo_ns = DEFAULT_VECTOR_TMO;
return conf;
free_bitmap:
free_em_conf:
free(em_conf);
free_conf:
free(conf);
return NULL;
}
void
eh_conf_uninit(struct eh_conf *conf)
{
struct eventmode_conf *em_conf = NULL;
if (!conf || !conf->mode_params)
return;
em_conf = conf->mode_params;
free(em_conf);
free(conf);
}
void
eh_display_conf(struct eh_conf *conf)
{
struct eventmode_conf *em_conf;
if (conf == NULL) {
EH_LOG_ERR("Invalid event helper configuration");
return;
}
if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
return;
if (conf->mode_params == NULL) {
EH_LOG_ERR("Invalid event mode parameters");
return;
}
em_conf = (struct eventmode_conf *)(conf->mode_params);
eh_display_operating_mode(em_conf);
eh_display_event_dev_conf(em_conf);
eh_display_rx_adapter_conf(em_conf);
eh_display_tx_adapter_conf(em_conf);
eh_display_link_conf(em_conf);
}
int32_t
eh_devs_init(struct eh_conf *conf)
{
struct eventmode_conf *em_conf;
uint16_t port_id;
int ret;
if (conf == NULL) {
EH_LOG_ERR("Invalid event helper configuration");
return -EINVAL;
}
if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
return 0;
if (conf->mode_params == NULL) {
EH_LOG_ERR("Invalid event mode parameters");
return -EINVAL;
}
em_conf = conf->mode_params;
em_conf->eth_portmask = conf->eth_portmask;
ret = eh_validate_conf(em_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to validate the requested config %d", ret);
return ret;
}
eh_display_conf(conf);
if ((conf->eth_portmask & (1 << port_id)) == 0)
continue;
if (ret != 0) {
EH_LOG_ERR("Failed to stop port %u, err: %d",
port_id, ret);
return ret;
}
}
ret = eh_initialize_eventdev(em_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to initialize event dev %d", ret);
return ret;
}
ret = eh_initialize_crypto_adapter(em_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to start event dev %d", ret);
return ret;
}
ret = eh_initialize_rx_adapter(em_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to initialize rx adapter %d", ret);
return ret;
}
ret = eh_initialize_tx_adapter(em_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to initialize tx adapter %d", ret);
return ret;
}
ret = eh_start_eventdev(em_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to start event dev %d", ret);
return ret;
}
ret = eh_start_crypto_adapter(em_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to start event crypto dev %d", ret);
return ret;
}
if ((conf->eth_portmask & (1 << port_id)) == 0)
continue;
if (ret < 0) {
EH_LOG_ERR("Failed to start eth dev %d, %d",
port_id, ret);
return ret;
}
}
return 0;
}
int32_t
eh_devs_uninit(struct eh_conf *conf)
{
struct eventmode_conf *em_conf;
int ret, i, j;
uint16_t id;
if (conf == NULL) {
EH_LOG_ERR("Invalid event helper configuration");
return -EINVAL;
}
if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
return 0;
if (conf->mode_params == NULL) {
EH_LOG_ERR("Invalid event mode parameters");
return -EINVAL;
}
em_conf = conf->mode_params;
for (i = 0; i < em_conf->nb_rx_adapter; i++) {
id = em_conf->rx_adapter[i].adapter_id;
if (ret < 0) {
EH_LOG_ERR("Failed to stop rx adapter %d", ret);
return ret;
}
for (j = 0; j < em_conf->rx_adapter[i].nb_connections; j++) {
em_conf->rx_adapter[i].conn[j].ethdev_id, -1);
if (ret < 0) {
EH_LOG_ERR(
"Failed to remove rx adapter queues %d",
ret);
return ret;
}
}
if (ret < 0) {
EH_LOG_ERR("Failed to free rx adapter %d", ret);
return ret;
}
}
ret = eh_stop_crypto_adapter(em_conf);
if (ret < 0) {
EH_LOG_ERR("Failed to start event crypto dev %d", ret);
return ret;
}
for (i = 0; i < em_conf->nb_eventdev; i++) {
id = em_conf->eventdev_config[i].eventdev_id;
if (ret < 0) {
EH_LOG_ERR("Failed to close event dev %d, %d", id, ret);
return ret;
}
}
for (i = 0; i < em_conf->nb_tx_adapter; i++) {
id = em_conf->tx_adapter[i].adapter_id;
if (ret < 0) {
EH_LOG_ERR("Failed to stop tx adapter %d", ret);
return ret;
}
for (j = 0; j < em_conf->tx_adapter[i].nb_connections; j++) {
em_conf->tx_adapter[i].conn[j].ethdev_id, -1);
if (ret < 0) {
EH_LOG_ERR(
"Failed to remove tx adapter queues %d",
ret);
return ret;
}
}
if (ret < 0) {
EH_LOG_ERR("Failed to free tx adapter %d", ret);
return ret;
}
}
return 0;
}
void
eh_launch_worker(struct eh_conf *conf, struct eh_app_worker_params *app_wrkr,
uint8_t nb_wrkr_param)
{
struct eh_app_worker_params *match_wrkr;
struct eh_event_link_info *links = NULL;
struct eventmode_conf *em_conf;
uint32_t lcore_id;
uint8_t nb_links;
if (conf == NULL) {
EH_LOG_ERR("Invalid event helper configuration");
return;
}
if (conf->mode_params == NULL) {
EH_LOG_ERR("Invalid event mode parameters");
return;
}
em_conf = conf->mode_params;
eh_start_worker_eth_core(em_conf, lcore_id);
return;
}
if (app_wrkr == NULL || nb_wrkr_param == 0) {
EH_LOG_ERR("Invalid args");
return;
}
match_wrkr = eh_find_worker(lcore_id, conf, app_wrkr, nb_wrkr_param);
if (match_wrkr == NULL) {
EH_LOG_ERR("Failed to match worker registered for lcore %d",
lcore_id);
goto clean_and_exit;
}
if (eh_verify_match_worker(match_wrkr) != 1) {
EH_LOG_ERR("Failed to validate the matched worker");
goto clean_and_exit;
}
nb_links = eh_get_event_lcore_links(lcore_id, conf, &links);
match_wrkr->worker_thread(links, nb_links);
free(links);
clean_and_exit:
eh_stop_worker_eth_core();
}
uint8_t
eh_get_tx_queue(struct eh_conf *conf, uint8_t eventdev_id)
{
struct eventdev_params *eventdev_config;
struct eventmode_conf *em_conf;
if (conf == NULL) {
EH_LOG_ERR("Invalid event helper configuration");
return -EINVAL;
}
if (conf->mode_params == NULL) {
EH_LOG_ERR("Invalid event mode parameters");
return -EINVAL;
}
em_conf = conf->mode_params;
eventdev_config = eh_get_eventdev_params(em_conf, eventdev_id);
if (eventdev_config == NULL) {
EH_LOG_ERR("Failed to read eventdev config");
return -EINVAL;
}
return eventdev_config->nb_eventqueue - 1;
}