diff options
Diffstat (limited to 'src/spdk/dpdk/drivers/bus/fslmc/portal')
-rw-r--r-- | src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 123 | ||||
-rw-r--r-- | src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpci.c | 187 | ||||
-rw-r--r-- | src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 527 | ||||
-rw-r--r-- | src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 52 | ||||
-rw-r--r-- | src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 379 |
5 files changed, 1268 insertions, 0 deletions
diff --git a/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c new file mode 100644 index 00000000..39c5adf9 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. + * Copyright 2016 NXP + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <sys/types.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> + +#include <rte_malloc.h> +#include <rte_memcpy.h> +#include <rte_string_fns.h> +#include <rte_cycles.h> +#include <rte_kvargs.h> +#include <rte_dev.h> +#include <rte_ethdev_driver.h> +#include <rte_mbuf_pool_ops.h> + +#include <fslmc_logs.h> +#include <rte_fslmc.h> +#include <mc/fsl_dpbp.h> +#include "portal/dpaa2_hw_pvt.h" +#include "portal/dpaa2_hw_dpio.h" + +TAILQ_HEAD(dpbp_dev_list, dpaa2_dpbp_dev); +static struct dpbp_dev_list dpbp_dev_list + = TAILQ_HEAD_INITIALIZER(dpbp_dev_list); /*!< DPBP device list */ + +static int +dpaa2_create_dpbp_device(int vdev_fd __rte_unused, + struct vfio_device_info *obj_info __rte_unused, + int dpbp_id) +{ + struct dpaa2_dpbp_dev *dpbp_node; + int ret; + static int register_once; + + /* Allocate DPAA2 dpbp handle */ + dpbp_node = rte_malloc(NULL, sizeof(struct dpaa2_dpbp_dev), 0); + if (!dpbp_node) { + DPAA2_BUS_ERR("Memory allocation failed for DPBP Device"); + return -1; + } + + /* Open the dpbp object */ + dpbp_node->dpbp.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX]; + ret = dpbp_open(&dpbp_node->dpbp, + CMD_PRI_LOW, dpbp_id, &dpbp_node->token); + if (ret) { + DPAA2_BUS_ERR("Unable to open buffer pool object: err(%d)", + ret); + rte_free(dpbp_node); + return -1; + } + + /* Clean the device first */ + ret = dpbp_reset(&dpbp_node->dpbp, CMD_PRI_LOW, dpbp_node->token); + if (ret) { + DPAA2_BUS_ERR("Unable to reset buffer pool device. err(%d)", + ret); + dpbp_close(&dpbp_node->dpbp, CMD_PRI_LOW, dpbp_node->token); + rte_free(dpbp_node); + return -1; + } + + dpbp_node->dpbp_id = dpbp_id; + rte_atomic16_init(&dpbp_node->in_use); + + TAILQ_INSERT_TAIL(&dpbp_dev_list, dpbp_node, next); + + if (!register_once) { + rte_mbuf_set_platform_mempool_ops(DPAA2_MEMPOOL_OPS_NAME); + register_once = 1; + } + + return 0; +} + +struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void) +{ + struct dpaa2_dpbp_dev *dpbp_dev = NULL; + + /* Get DPBP dev handle from list using index */ + TAILQ_FOREACH(dpbp_dev, &dpbp_dev_list, next) { + if (dpbp_dev && rte_atomic16_test_and_set(&dpbp_dev->in_use)) + break; + } + + return dpbp_dev; +} + +void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp) +{ + struct dpaa2_dpbp_dev *dpbp_dev = NULL; + + /* Match DPBP handle and mark it free */ + TAILQ_FOREACH(dpbp_dev, &dpbp_dev_list, next) { + if (dpbp_dev == dpbp) { + rte_atomic16_dec(&dpbp_dev->in_use); + return; + } + } +} + +int dpaa2_dpbp_supported(void) +{ + if (TAILQ_EMPTY(&dpbp_dev_list)) + return -1; + return 0; +} + +static struct rte_dpaa2_object rte_dpaa2_dpbp_obj = { + .dev_type = DPAA2_BPOOL, + .create = dpaa2_create_dpbp_device, +}; + +RTE_PMD_REGISTER_DPAA2_OBJECT(dpbp, rte_dpaa2_dpbp_obj); diff --git a/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpci.c b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpci.c new file mode 100644 index 00000000..5ad0374d --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpci.c @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2017 NXP + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <sys/types.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> + +#include <rte_malloc.h> +#include <rte_memcpy.h> +#include <rte_string_fns.h> +#include <rte_cycles.h> +#include <rte_kvargs.h> +#include <rte_dev.h> +#include <rte_ethdev_driver.h> + +#include <fslmc_logs.h> +#include <rte_fslmc.h> +#include <mc/fsl_dpci.h> +#include "portal/dpaa2_hw_pvt.h" +#include "portal/dpaa2_hw_dpio.h" + +TAILQ_HEAD(dpci_dev_list, dpaa2_dpci_dev); +static struct dpci_dev_list dpci_dev_list + = TAILQ_HEAD_INITIALIZER(dpci_dev_list); /*!< DPCI device list */ + +static int +rte_dpaa2_create_dpci_device(int vdev_fd __rte_unused, + struct vfio_device_info *obj_info __rte_unused, + int dpci_id) +{ + struct dpaa2_dpci_dev *dpci_node; + struct dpci_attr attr; + struct dpci_rx_queue_cfg rx_queue_cfg; + struct dpci_rx_queue_attr rx_attr; + struct dpci_tx_queue_attr tx_attr; + int ret, i; + + /* Allocate DPAA2 dpci handle */ + dpci_node = rte_malloc(NULL, sizeof(struct dpaa2_dpci_dev), 0); + if (!dpci_node) { + DPAA2_BUS_ERR("Memory allocation failed for DPCI Device"); + return -ENOMEM; + } + + /* Open the dpci object */ + dpci_node->dpci.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX]; + ret = dpci_open(&dpci_node->dpci, + CMD_PRI_LOW, dpci_id, &dpci_node->token); + if (ret) { + DPAA2_BUS_ERR("Resource alloc failure with err code: %d", ret); + goto err; + } + + /* Get the device attributes */ + ret = dpci_get_attributes(&dpci_node->dpci, + CMD_PRI_LOW, dpci_node->token, &attr); + if (ret != 0) { + DPAA2_BUS_ERR("Reading device failed with err code: %d", ret); + goto err; + } + + for (i = 0; i < DPAA2_DPCI_MAX_QUEUES; i++) { + struct dpaa2_queue *rxq; + + memset(&rx_queue_cfg, 0, sizeof(struct dpci_rx_queue_cfg)); + ret = dpci_set_rx_queue(&dpci_node->dpci, + CMD_PRI_LOW, + dpci_node->token, + i, &rx_queue_cfg); + if (ret) { + DPAA2_BUS_ERR("Setting Rx queue failed with err code: %d", + ret); + goto err; + } + + /* Allocate DQ storage for the DPCI Rx queues */ + rxq = &(dpci_node->rx_queue[i]); + rxq->q_storage = rte_malloc("dq_storage", + sizeof(struct queue_storage_info_t), + RTE_CACHE_LINE_SIZE); + if (!rxq->q_storage) { + DPAA2_BUS_ERR("q_storage allocation failed\n"); + ret = -ENOMEM; + goto err; + } + + memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t)); + ret = dpaa2_alloc_dq_storage(rxq->q_storage); + if (ret) { + DPAA2_BUS_ERR("dpaa2_alloc_dq_storage failed\n"); + goto err; + } + } + + /* Enable the device */ + ret = dpci_enable(&dpci_node->dpci, + CMD_PRI_LOW, dpci_node->token); + if (ret != 0) { + DPAA2_BUS_ERR("Enabling device failed with err code: %d", ret); + goto err; + } + + for (i = 0; i < DPAA2_DPCI_MAX_QUEUES; i++) { + /* Get the Rx FQID's */ + ret = dpci_get_rx_queue(&dpci_node->dpci, + CMD_PRI_LOW, + dpci_node->token, i, + &rx_attr); + if (ret != 0) { + DPAA2_BUS_ERR("Rx queue fetch failed with err code: %d", + ret); + goto err; + } + dpci_node->rx_queue[i].fqid = rx_attr.fqid; + + ret = dpci_get_tx_queue(&dpci_node->dpci, + CMD_PRI_LOW, + dpci_node->token, i, + &tx_attr); + if (ret != 0) { + DPAA2_BUS_ERR("Reading device failed with err code: %d", + ret); + goto err; + } + dpci_node->tx_queue[i].fqid = tx_attr.fqid; + } + + dpci_node->dpci_id = dpci_id; + rte_atomic16_init(&dpci_node->in_use); + + TAILQ_INSERT_TAIL(&dpci_dev_list, dpci_node, next); + + return 0; + +err: + for (i = 0; i < DPAA2_DPCI_MAX_QUEUES; i++) { + struct dpaa2_queue *rxq = &(dpci_node->rx_queue[i]); + + if (rxq->q_storage) { + dpaa2_free_dq_storage(rxq->q_storage); + rte_free(rxq->q_storage); + } + } + rte_free(dpci_node); + + return ret; +} + +struct dpaa2_dpci_dev *rte_dpaa2_alloc_dpci_dev(void) +{ + struct dpaa2_dpci_dev *dpci_dev = NULL; + + /* Get DPCI dev handle from list using index */ + TAILQ_FOREACH(dpci_dev, &dpci_dev_list, next) { + if (dpci_dev && rte_atomic16_test_and_set(&dpci_dev->in_use)) + break; + } + + return dpci_dev; +} + +void rte_dpaa2_free_dpci_dev(struct dpaa2_dpci_dev *dpci) +{ + struct dpaa2_dpci_dev *dpci_dev = NULL; + + /* Match DPCI handle and mark it free */ + TAILQ_FOREACH(dpci_dev, &dpci_dev_list, next) { + if (dpci_dev == dpci) { + rte_atomic16_dec(&dpci_dev->in_use); + return; + } + } +} + +static struct rte_dpaa2_object rte_dpaa2_dpci_obj = { + .dev_type = DPAA2_CI, + .create = rte_dpaa2_create_dpci_device, +}; + +RTE_PMD_REGISTER_DPAA2_OBJECT(dpci, rte_dpaa2_dpci_obj); diff --git a/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c new file mode 100644 index 00000000..99f70be1 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c @@ -0,0 +1,527 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. + * Copyright 2016 NXP + * + */ +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <stdarg.h> +#include <inttypes.h> +#include <signal.h> +#include <pthread.h> +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/syscall.h> +#include <sys/epoll.h> +#include<sys/eventfd.h> + +#include <rte_mbuf.h> +#include <rte_ethdev_driver.h> +#include <rte_malloc.h> +#include <rte_memcpy.h> +#include <rte_string_fns.h> +#include <rte_cycles.h> +#include <rte_kvargs.h> +#include <rte_dev.h> + +#include <fslmc_logs.h> +#include <rte_fslmc.h> +#include "dpaa2_hw_pvt.h" +#include "dpaa2_hw_dpio.h" +#include <mc/fsl_dpmng.h> + +#define NUM_HOST_CPUS RTE_MAX_LCORE + +struct dpaa2_io_portal_t dpaa2_io_portal[RTE_MAX_LCORE]; +RTE_DEFINE_PER_LCORE(struct dpaa2_io_portal_t, _dpaa2_io); + +struct swp_active_dqs rte_global_active_dqs_list[NUM_MAX_SWP]; + +TAILQ_HEAD(dpio_dev_list, dpaa2_dpio_dev); +static struct dpio_dev_list dpio_dev_list + = TAILQ_HEAD_INITIALIZER(dpio_dev_list); /*!< DPIO device list */ +static uint32_t io_space_count; + +/* Variable to store DPAA2 platform type */ +uint32_t dpaa2_svr_family; + +/*Stashing Macros default for LS208x*/ +static int dpaa2_core_cluster_base = 0x04; +static int dpaa2_cluster_sz = 2; + +/* For LS208X platform There are four clusters with following mapping: + * Cluster 1 (ID = x04) : CPU0, CPU1; + * Cluster 2 (ID = x05) : CPU2, CPU3; + * Cluster 3 (ID = x06) : CPU4, CPU5; + * Cluster 4 (ID = x07) : CPU6, CPU7; + */ +/* For LS108X platform There are two clusters with following mapping: + * Cluster 1 (ID = x02) : CPU0, CPU1, CPU2, CPU3; + * Cluster 2 (ID = x03) : CPU4, CPU5, CPU6, CPU7; + */ +/* For LX2160 platform There are four clusters with following mapping: + * Cluster 1 (ID = x00) : CPU0, CPU1; + * Cluster 2 (ID = x01) : CPU2, CPU3; + * Cluster 3 (ID = x02) : CPU4, CPU5; + * Cluster 4 (ID = x03) : CPU6, CPU7; + * Cluster 1 (ID = x04) : CPU8, CPU9; + * Cluster 2 (ID = x05) : CPU10, CP11; + * Cluster 3 (ID = x06) : CPU12, CPU13; + * Cluster 4 (ID = x07) : CPU14, CPU15; + */ + +static int +dpaa2_core_cluster_sdest(int cpu_id) +{ + int x = cpu_id / dpaa2_cluster_sz; + + return dpaa2_core_cluster_base + x; +} + +#ifdef RTE_LIBRTE_PMD_DPAA2_EVENTDEV +static void dpaa2_affine_dpio_intr_to_respective_core(int32_t dpio_id) +{ +#define STRING_LEN 28 +#define COMMAND_LEN 50 + uint32_t cpu_mask = 1; + int ret; + size_t len = 0; + char *temp = NULL, *token = NULL; + char string[STRING_LEN], command[COMMAND_LEN]; + FILE *file; + + snprintf(string, STRING_LEN, "dpio.%d", dpio_id); + file = fopen("/proc/interrupts", "r"); + if (!file) { + DPAA2_BUS_WARN("Failed to open /proc/interrupts file"); + return; + } + while (getline(&temp, &len, file) != -1) { + if ((strstr(temp, string)) != NULL) { + token = strtok(temp, ":"); + break; + } + } + + if (!token) { + DPAA2_BUS_WARN("Failed to get interrupt id for dpio.%d", + dpio_id); + if (temp) + free(temp); + fclose(file); + return; + } + + cpu_mask = cpu_mask << rte_lcore_id(); + snprintf(command, COMMAND_LEN, "echo %X > /proc/irq/%s/smp_affinity", + cpu_mask, token); + ret = system(command); + if (ret < 0) + DPAA2_BUS_WARN( + "Failed to affine interrupts on respective core"); + else + DPAA2_BUS_DEBUG(" %s command is executed", command); + + free(temp); + fclose(file); +} + +static int dpaa2_dpio_intr_init(struct dpaa2_dpio_dev *dpio_dev) +{ + struct epoll_event epoll_ev; + int eventfd, dpio_epoll_fd, ret; + int threshold = 0x3, timeout = 0xFF; + + dpio_epoll_fd = epoll_create(1); + ret = rte_dpaa2_intr_enable(&dpio_dev->intr_handle, 0); + if (ret) { + DPAA2_BUS_ERR("Interrupt registeration failed"); + return -1; + } + + if (getenv("DPAA2_PORTAL_INTR_THRESHOLD")) + threshold = atoi(getenv("DPAA2_PORTAL_INTR_THRESHOLD")); + + if (getenv("DPAA2_PORTAL_INTR_TIMEOUT")) + sscanf(getenv("DPAA2_PORTAL_INTR_TIMEOUT"), "%x", &timeout); + + qbman_swp_interrupt_set_trigger(dpio_dev->sw_portal, + QBMAN_SWP_INTERRUPT_DQRI); + qbman_swp_interrupt_clear_status(dpio_dev->sw_portal, 0xffffffff); + qbman_swp_interrupt_set_inhibit(dpio_dev->sw_portal, 0); + qbman_swp_dqrr_thrshld_write(dpio_dev->sw_portal, threshold); + qbman_swp_intr_timeout_write(dpio_dev->sw_portal, timeout); + + eventfd = dpio_dev->intr_handle.fd; + epoll_ev.events = EPOLLIN | EPOLLPRI | EPOLLET; + epoll_ev.data.fd = eventfd; + + ret = epoll_ctl(dpio_epoll_fd, EPOLL_CTL_ADD, eventfd, &epoll_ev); + if (ret < 0) { + DPAA2_BUS_ERR("epoll_ctl failed"); + return -1; + } + dpio_dev->epoll_fd = dpio_epoll_fd; + + dpaa2_affine_dpio_intr_to_respective_core(dpio_dev->hw_id); + + return 0; +} +#endif + +static int +configure_dpio_qbman_swp(struct dpaa2_dpio_dev *dpio_dev) +{ + struct qbman_swp_desc p_des; + struct dpio_attr attr; + + dpio_dev->dpio = malloc(sizeof(struct fsl_mc_io)); + if (!dpio_dev->dpio) { + DPAA2_BUS_ERR("Memory allocation failure"); + return -1; + } + + dpio_dev->dpio->regs = dpio_dev->mc_portal; + if (dpio_open(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->hw_id, + &dpio_dev->token)) { + DPAA2_BUS_ERR("Failed to allocate IO space"); + free(dpio_dev->dpio); + return -1; + } + + if (dpio_reset(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token)) { + DPAA2_BUS_ERR("Failed to reset dpio"); + dpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token); + free(dpio_dev->dpio); + return -1; + } + + if (dpio_enable(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token)) { + DPAA2_BUS_ERR("Failed to Enable dpio"); + dpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token); + free(dpio_dev->dpio); + return -1; + } + + if (dpio_get_attributes(dpio_dev->dpio, CMD_PRI_LOW, + dpio_dev->token, &attr)) { + DPAA2_BUS_ERR("DPIO Get attribute failed"); + dpio_disable(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token); + dpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token); + free(dpio_dev->dpio); + return -1; + } + + /* Configure & setup SW portal */ + p_des.block = NULL; + p_des.idx = attr.qbman_portal_id; + p_des.cena_bar = (void *)(dpio_dev->qbman_portal_ce_paddr); + p_des.cinh_bar = (void *)(dpio_dev->qbman_portal_ci_paddr); + p_des.irq = -1; + p_des.qman_version = attr.qbman_version; + + dpio_dev->sw_portal = qbman_swp_init(&p_des); + if (dpio_dev->sw_portal == NULL) { + DPAA2_BUS_ERR("QBMan SW Portal Init failed"); + dpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token); + free(dpio_dev->dpio); + return -1; + } + + return 0; +} + +static int +dpaa2_configure_stashing(struct dpaa2_dpio_dev *dpio_dev, int cpu_id) +{ + int sdest, ret; + + /* Set the Stashing Destination */ + if (cpu_id < 0) { + cpu_id = rte_get_master_lcore(); + if (cpu_id < 0) { + DPAA2_BUS_ERR("Getting CPU Index failed"); + return -1; + } + } + /* Set the STASH Destination depending on Current CPU ID. + * Valid values of SDEST are 4,5,6,7. Where, + */ + + sdest = dpaa2_core_cluster_sdest(cpu_id); + DPAA2_BUS_DEBUG("Portal= %d CPU= %u SDEST= %d", + dpio_dev->index, cpu_id, sdest); + + ret = dpio_set_stashing_destination(dpio_dev->dpio, CMD_PRI_LOW, + dpio_dev->token, sdest); + if (ret) { + DPAA2_BUS_ERR("%d ERROR in SDEST", ret); + return -1; + } + +#ifdef RTE_LIBRTE_PMD_DPAA2_EVENTDEV + if (dpaa2_dpio_intr_init(dpio_dev)) { + DPAA2_BUS_ERR("Interrupt registration failed for dpio"); + return -1; + } +#endif + + return 0; +} + +struct dpaa2_dpio_dev *dpaa2_get_qbman_swp(int cpu_id) +{ + struct dpaa2_dpio_dev *dpio_dev = NULL; + int ret; + + /* Get DPIO dev handle from list using index */ + TAILQ_FOREACH(dpio_dev, &dpio_dev_list, next) { + if (dpio_dev && rte_atomic16_test_and_set(&dpio_dev->ref_count)) + break; + } + if (!dpio_dev) + return NULL; + + DPAA2_BUS_DEBUG("New Portal %p (%d) affined thread - %lu", + dpio_dev, dpio_dev->index, syscall(SYS_gettid)); + + ret = dpaa2_configure_stashing(dpio_dev, cpu_id); + if (ret) + DPAA2_BUS_ERR("dpaa2_configure_stashing failed"); + + return dpio_dev; +} + +int +dpaa2_affine_qbman_swp(void) +{ + unsigned int lcore_id = rte_lcore_id(); + uint64_t tid = syscall(SYS_gettid); + + if (lcore_id == LCORE_ID_ANY) + lcore_id = rte_get_master_lcore(); + /* if the core id is not supported */ + else if (lcore_id >= RTE_MAX_LCORE) + return -1; + + if (dpaa2_io_portal[lcore_id].dpio_dev) { + DPAA2_BUS_DP_INFO("DPAA Portal=%p (%d) is being shared" + " between thread %" PRIu64 " and current " + "%" PRIu64 "\n", + dpaa2_io_portal[lcore_id].dpio_dev, + dpaa2_io_portal[lcore_id].dpio_dev->index, + dpaa2_io_portal[lcore_id].net_tid, + tid); + RTE_PER_LCORE(_dpaa2_io).dpio_dev + = dpaa2_io_portal[lcore_id].dpio_dev; + rte_atomic16_inc(&dpaa2_io_portal + [lcore_id].dpio_dev->ref_count); + dpaa2_io_portal[lcore_id].net_tid = tid; + + DPAA2_BUS_DP_DEBUG("Old Portal=%p (%d) affined thread - " + "%" PRIu64 "\n", + dpaa2_io_portal[lcore_id].dpio_dev, + dpaa2_io_portal[lcore_id].dpio_dev->index, + tid); + return 0; + } + + /* Populate the dpaa2_io_portal structure */ + dpaa2_io_portal[lcore_id].dpio_dev = dpaa2_get_qbman_swp(lcore_id); + + if (dpaa2_io_portal[lcore_id].dpio_dev) { + RTE_PER_LCORE(_dpaa2_io).dpio_dev + = dpaa2_io_portal[lcore_id].dpio_dev; + dpaa2_io_portal[lcore_id].net_tid = tid; + + return 0; + } else { + return -1; + } +} + +int +dpaa2_affine_qbman_ethrx_swp(void) +{ + unsigned int lcore_id = rte_lcore_id(); + uint64_t tid = syscall(SYS_gettid); + + if (lcore_id == LCORE_ID_ANY) + lcore_id = rte_get_master_lcore(); + /* if the core id is not supported */ + else if (lcore_id >= RTE_MAX_LCORE) + return -1; + + if (dpaa2_io_portal[lcore_id].ethrx_dpio_dev) { + DPAA2_BUS_DP_INFO( + "DPAA Portal=%p (%d) is being shared between thread" + " %" PRIu64 " and current %" PRIu64 "\n", + dpaa2_io_portal[lcore_id].ethrx_dpio_dev, + dpaa2_io_portal[lcore_id].ethrx_dpio_dev->index, + dpaa2_io_portal[lcore_id].sec_tid, + tid); + RTE_PER_LCORE(_dpaa2_io).ethrx_dpio_dev + = dpaa2_io_portal[lcore_id].ethrx_dpio_dev; + rte_atomic16_inc(&dpaa2_io_portal + [lcore_id].ethrx_dpio_dev->ref_count); + dpaa2_io_portal[lcore_id].sec_tid = tid; + + DPAA2_BUS_DP_DEBUG( + "Old Portal=%p (%d) affined thread" + " - %" PRIu64 "\n", + dpaa2_io_portal[lcore_id].ethrx_dpio_dev, + dpaa2_io_portal[lcore_id].ethrx_dpio_dev->index, + tid); + return 0; + } + + /* Populate the dpaa2_io_portal structure */ + dpaa2_io_portal[lcore_id].ethrx_dpio_dev = + dpaa2_get_qbman_swp(lcore_id); + + if (dpaa2_io_portal[lcore_id].ethrx_dpio_dev) { + RTE_PER_LCORE(_dpaa2_io).ethrx_dpio_dev + = dpaa2_io_portal[lcore_id].ethrx_dpio_dev; + dpaa2_io_portal[lcore_id].sec_tid = tid; + return 0; + } else { + return -1; + } +} + +static int +dpaa2_create_dpio_device(int vdev_fd, + struct vfio_device_info *obj_info, + int object_id) +{ + struct dpaa2_dpio_dev *dpio_dev; + struct vfio_region_info reg_info = { .argsz = sizeof(reg_info)}; + + if (obj_info->num_regions < NUM_DPIO_REGIONS) { + DPAA2_BUS_ERR("Not sufficient number of DPIO regions"); + return -1; + } + + dpio_dev = rte_malloc(NULL, sizeof(struct dpaa2_dpio_dev), + RTE_CACHE_LINE_SIZE); + if (!dpio_dev) { + DPAA2_BUS_ERR("Memory allocation failed for DPIO Device"); + return -1; + } + + dpio_dev->dpio = NULL; + dpio_dev->hw_id = object_id; + rte_atomic16_init(&dpio_dev->ref_count); + /* Using single portal for all devices */ + dpio_dev->mc_portal = rte_mcp_ptr_list[MC_PORTAL_INDEX]; + + reg_info.index = 0; + if (ioctl(vdev_fd, VFIO_DEVICE_GET_REGION_INFO, ®_info)) { + DPAA2_BUS_ERR("vfio: error getting region info"); + rte_free(dpio_dev); + return -1; + } + + dpio_dev->ce_size = reg_info.size; + dpio_dev->qbman_portal_ce_paddr = (size_t)mmap(NULL, reg_info.size, + PROT_WRITE | PROT_READ, MAP_SHARED, + vdev_fd, reg_info.offset); + + reg_info.index = 1; + if (ioctl(vdev_fd, VFIO_DEVICE_GET_REGION_INFO, ®_info)) { + DPAA2_BUS_ERR("vfio: error getting region info"); + rte_free(dpio_dev); + return -1; + } + + dpio_dev->ci_size = reg_info.size; + dpio_dev->qbman_portal_ci_paddr = (size_t)mmap(NULL, reg_info.size, + PROT_WRITE | PROT_READ, MAP_SHARED, + vdev_fd, reg_info.offset); + + if (configure_dpio_qbman_swp(dpio_dev)) { + DPAA2_BUS_ERR( + "Fail to configure the dpio qbman portal for %d", + dpio_dev->hw_id); + rte_free(dpio_dev); + return -1; + } + + io_space_count++; + dpio_dev->index = io_space_count; + + if (rte_dpaa2_vfio_setup_intr(&dpio_dev->intr_handle, vdev_fd, 1)) { + DPAA2_BUS_ERR("Fail to setup interrupt for %d", + dpio_dev->hw_id); + rte_free(dpio_dev); + } + + /* find the SoC type for the first time */ + if (!dpaa2_svr_family) { + struct mc_soc_version mc_plat_info = {0}; + + if (mc_get_soc_version(dpio_dev->dpio, + CMD_PRI_LOW, &mc_plat_info)) { + DPAA2_BUS_ERR("Unable to get SoC version information"); + } else if ((mc_plat_info.svr & 0xffff0000) == SVR_LS1080A) { + dpaa2_core_cluster_base = 0x02; + dpaa2_cluster_sz = 4; + DPAA2_BUS_DEBUG("LS108x (A53) Platform Detected"); + } else if ((mc_plat_info.svr & 0xffff0000) == SVR_LX2160A) { + dpaa2_core_cluster_base = 0x00; + dpaa2_cluster_sz = 2; + DPAA2_BUS_DEBUG("LX2160 Platform Detected"); + } + dpaa2_svr_family = (mc_plat_info.svr & 0xffff0000); + } + + TAILQ_INSERT_TAIL(&dpio_dev_list, dpio_dev, next); + + return 0; +} + +void +dpaa2_free_dq_storage(struct queue_storage_info_t *q_storage) +{ + int i = 0; + + for (i = 0; i < NUM_DQS_PER_QUEUE; i++) { + if (q_storage->dq_storage[i]) + rte_free(q_storage->dq_storage[i]); + } +} + +int +dpaa2_alloc_dq_storage(struct queue_storage_info_t *q_storage) +{ + int i = 0; + + for (i = 0; i < NUM_DQS_PER_QUEUE; i++) { + q_storage->dq_storage[i] = rte_malloc(NULL, + DPAA2_DQRR_RING_SIZE * sizeof(struct qbman_result), + RTE_CACHE_LINE_SIZE); + if (!q_storage->dq_storage[i]) + goto fail; + } + return 0; +fail: + while (--i >= 0) + rte_free(q_storage->dq_storage[i]); + + return -1; +} + +static struct rte_dpaa2_object rte_dpaa2_dpio_obj = { + .dev_type = DPAA2_IO, + .create = dpaa2_create_dpio_device, +}; + +RTE_PMD_REGISTER_DPAA2_OBJECT(dpio, rte_dpaa2_dpio_obj); diff --git a/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h new file mode 100644 index 00000000..d593eea7 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. + * Copyright 2016 NXP + * + */ + +#ifndef _DPAA2_HW_DPIO_H_ +#define _DPAA2_HW_DPIO_H_ + +#include <mc/fsl_dpio.h> +#include <mc/fsl_mc_sys.h> + +struct dpaa2_io_portal_t { + struct dpaa2_dpio_dev *dpio_dev; + struct dpaa2_dpio_dev *ethrx_dpio_dev; + uint64_t net_tid; + uint64_t sec_tid; + void *eventdev; +}; + +/*! Global per thread DPIO portal */ +RTE_DECLARE_PER_LCORE(struct dpaa2_io_portal_t, _dpaa2_io); + +#define DPAA2_PER_LCORE_DPIO RTE_PER_LCORE(_dpaa2_io).dpio_dev +#define DPAA2_PER_LCORE_PORTAL DPAA2_PER_LCORE_DPIO->sw_portal + +#define DPAA2_PER_LCORE_ETHRX_DPIO RTE_PER_LCORE(_dpaa2_io).ethrx_dpio_dev +#define DPAA2_PER_LCORE_ETHRX_PORTAL DPAA2_PER_LCORE_ETHRX_DPIO->sw_portal + +/* Variable to store DPAA2 platform type */ +extern uint32_t dpaa2_svr_family; + +extern struct dpaa2_io_portal_t dpaa2_io_portal[RTE_MAX_LCORE]; + +struct dpaa2_dpio_dev *dpaa2_get_qbman_swp(int cpu_id); + +/* Affine a DPIO portal to current processing thread */ +int dpaa2_affine_qbman_swp(void); + +/* Affine additional DPIO portal to current crypto processing thread */ +int dpaa2_affine_qbman_ethrx_swp(void); + +/* allocate memory for FQ - dq storage */ +int +dpaa2_alloc_dq_storage(struct queue_storage_info_t *q_storage); + +/* free memory for FQ- dq storage */ +void +dpaa2_free_dq_storage(struct queue_storage_info_t *q_storage); + +#endif /* _DPAA2_HW_DPIO_H_ */ diff --git a/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h new file mode 100644 index 00000000..82075936 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h @@ -0,0 +1,379 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. + * Copyright 2016 NXP + * + */ + +#ifndef _DPAA2_HW_PVT_H_ +#define _DPAA2_HW_PVT_H_ + +#include <rte_eventdev.h> + +#include <mc/fsl_mc_sys.h> +#include <fsl_qbman_portal.h> + +#ifndef false +#define false 0 +#endif +#ifndef true +#define true 1 +#endif +#define lower_32_bits(x) ((uint32_t)(x)) +#define upper_32_bits(x) ((uint32_t)(((x) >> 16) >> 16)) + +#define SVR_LS1080A 0x87030000 +#define SVR_LS2080A 0x87010000 +#define SVR_LS2088A 0x87090000 +#define SVR_LX2160A 0x87360000 + +#ifndef VLAN_TAG_SIZE +#define VLAN_TAG_SIZE 4 /** < Vlan Header Length */ +#endif + +#define MAX_TX_RING_SLOTS 8 + /** <Maximum number of slots available in TX ring*/ + +#define DPAA2_DQRR_RING_SIZE 16 + /** <Maximum number of slots available in RX ring*/ + +#define MC_PORTAL_INDEX 0 +#define NUM_DPIO_REGIONS 2 +#define NUM_DQS_PER_QUEUE 2 + +/* Maximum release/acquire from QBMAN */ +#define DPAA2_MBUF_MAX_ACQ_REL 7 + +#define DPAA2_MEMPOOL_OPS_NAME "dpaa2" + +#define MAX_BPID 256 +#define DPAA2_MBUF_HW_ANNOTATION 64 +#define DPAA2_FD_PTA_SIZE 0 + +#if (DPAA2_MBUF_HW_ANNOTATION + DPAA2_FD_PTA_SIZE) > RTE_PKTMBUF_HEADROOM +#error "Annotation requirement is more than RTE_PKTMBUF_HEADROOM" +#endif + +/* we will re-use the HEADROOM for annotation in RX */ +#define DPAA2_HW_BUF_RESERVE 0 +#define DPAA2_PACKET_LAYOUT_ALIGN 64 /*changing from 256 */ + +#define DPAA2_DPCI_MAX_QUEUES 2 + +struct dpaa2_dpio_dev { + TAILQ_ENTRY(dpaa2_dpio_dev) next; + /**< Pointer to Next device instance */ + uint16_t index; /**< Index of a instance in the list */ + rte_atomic16_t ref_count; + /**< How many thread contexts are sharing this.*/ + struct fsl_mc_io *dpio; /** handle to DPIO portal object */ + uint16_t token; + struct qbman_swp *sw_portal; /** SW portal object */ + const struct qbman_result *dqrr[4]; + /**< DQRR Entry for this SW portal */ + void *mc_portal; /**< MC Portal for configuring this device */ + uintptr_t qbman_portal_ce_paddr; + /**< Physical address of Cache Enabled Area */ + uintptr_t ce_size; /**< Size of the CE region */ + uintptr_t qbman_portal_ci_paddr; + /**< Physical address of Cache Inhibit Area */ + uintptr_t ci_size; /**< Size of the CI region */ + struct rte_intr_handle intr_handle; /* Interrupt related info */ + int32_t epoll_fd; /**< File descriptor created for interrupt polling */ + int32_t hw_id; /**< An unique ID of this DPIO device instance */ +}; + +struct dpaa2_dpbp_dev { + TAILQ_ENTRY(dpaa2_dpbp_dev) next; + /**< Pointer to Next device instance */ + struct fsl_mc_io dpbp; /** handle to DPBP portal object */ + uint16_t token; + rte_atomic16_t in_use; + uint32_t dpbp_id; /*HW ID for DPBP object */ +}; + +struct queue_storage_info_t { + struct qbman_result *dq_storage[NUM_DQS_PER_QUEUE]; + struct qbman_result *active_dqs; + uint8_t active_dpio_id; + uint8_t toggle; + uint8_t last_num_pkts; +}; + +struct dpaa2_queue; + +typedef void (dpaa2_queue_cb_dqrr_t)(struct qbman_swp *swp, + const struct qbman_fd *fd, + const struct qbman_result *dq, + struct dpaa2_queue *rxq, + struct rte_event *ev); + +struct dpaa2_queue { + struct rte_mempool *mb_pool; /**< mbuf pool to populate RX ring. */ + void *dev; + int32_t eventfd; /*!< Event Fd of this queue */ + uint32_t fqid; /*!< Unique ID of this queue */ + uint8_t tc_index; /*!< traffic class identifier */ + uint16_t flow_id; /*!< To be used by DPAA2 frmework */ + uint64_t rx_pkts; + uint64_t tx_pkts; + uint64_t err_pkts; + union { + struct queue_storage_info_t *q_storage; + struct qbman_result *cscn; + }; + struct rte_event ev; + dpaa2_queue_cb_dqrr_t *cb; +}; + +struct swp_active_dqs { + struct qbman_result *global_active_dqs; + uint64_t reserved[7]; +}; + +#define NUM_MAX_SWP 64 + +extern struct swp_active_dqs rte_global_active_dqs_list[NUM_MAX_SWP]; + +struct dpaa2_dpci_dev { + TAILQ_ENTRY(dpaa2_dpci_dev) next; + /**< Pointer to Next device instance */ + struct fsl_mc_io dpci; /** handle to DPCI portal object */ + uint16_t token; + rte_atomic16_t in_use; + uint32_t dpci_id; /*HW ID for DPCI object */ + struct dpaa2_queue rx_queue[DPAA2_DPCI_MAX_QUEUES]; + struct dpaa2_queue tx_queue[DPAA2_DPCI_MAX_QUEUES]; +}; + +/*! Global MCP list */ +extern void *(*rte_mcp_ptr_list); + +/* Refer to Table 7-3 in SEC BG */ +struct qbman_fle { + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t length; + /* FMT must be 00, MSB is final bit */ + uint32_t fin_bpid_offset; + uint32_t frc; + uint32_t reserved[3]; /* Not used currently */ +}; + +struct qbman_sge { + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t length; + uint32_t fin_bpid_offset; +}; + +/* There are three types of frames: Single, Scatter Gather and Frame Lists */ +enum qbman_fd_format { + qbman_fd_single = 0, + qbman_fd_list, + qbman_fd_sg +}; +/*Macros to define operations on FD*/ +#define DPAA2_SET_FD_ADDR(fd, addr) do { \ + (fd)->simple.addr_lo = lower_32_bits((size_t)(addr)); \ + (fd)->simple.addr_hi = upper_32_bits((uint64_t)(addr)); \ +} while (0) +#define DPAA2_SET_FD_LEN(fd, length) ((fd)->simple.len = length) +#define DPAA2_SET_FD_BPID(fd, bpid) ((fd)->simple.bpid_offset |= bpid) +#define DPAA2_SET_ONLY_FD_BPID(fd, bpid) \ + ((fd)->simple.bpid_offset = bpid) +#define DPAA2_SET_FD_IVP(fd) (((fd)->simple.bpid_offset |= 0x00004000)) +#define DPAA2_SET_FD_OFFSET(fd, offset) \ + (((fd)->simple.bpid_offset |= (uint32_t)(offset) << 16)) +#define DPAA2_SET_FD_INTERNAL_JD(fd, len) \ + ((fd)->simple.frc = (0x80000000 | (len))) +#define DPAA2_GET_FD_FRC_PARSE_SUM(fd) \ + ((uint16_t)(((fd)->simple.frc & 0xffff0000) >> 16)) +#define DPAA2_SET_FD_FRC(fd, _frc) ((fd)->simple.frc = _frc) +#define DPAA2_RESET_FD_CTRL(fd) ((fd)->simple.ctrl = 0) + +#define DPAA2_SET_FD_ASAL(fd, asal) ((fd)->simple.ctrl |= (asal << 16)) +#define DPAA2_SET_FD_FLC(fd, addr) do { \ + (fd)->simple.flc_lo = lower_32_bits((size_t)(addr)); \ + (fd)->simple.flc_hi = upper_32_bits((uint64_t)(addr)); \ +} while (0) +#define DPAA2_SET_FLE_INTERNAL_JD(fle, len) ((fle)->frc = (0x80000000 | (len))) +#define DPAA2_GET_FLE_ADDR(fle) \ + (size_t)((((uint64_t)((fle)->addr_hi)) << 32) + (fle)->addr_lo) +#define DPAA2_SET_FLE_ADDR(fle, addr) do { \ + (fle)->addr_lo = lower_32_bits((size_t)addr); \ + (fle)->addr_hi = upper_32_bits((uint64_t)addr); \ +} while (0) +#define DPAA2_GET_FLE_CTXT(fle) \ + ((((uint64_t)((fle)->reserved[1])) << 32) + (fle)->reserved[0]) +#define DPAA2_FLE_SAVE_CTXT(fle, addr) do { \ + (fle)->reserved[0] = lower_32_bits((size_t)addr); \ + (fle)->reserved[1] = upper_32_bits((uint64_t)addr); \ +} while (0) +#define DPAA2_SET_FLE_OFFSET(fle, offset) \ + ((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16) +#define DPAA2_SET_FLE_LEN(fle, len) ((fle)->length = len) +#define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid) +#define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff) +#define DPAA2_SET_FLE_FIN(fle) ((fle)->fin_bpid_offset |= 1 << 31) +#define DPAA2_SET_FLE_IVP(fle) (((fle)->fin_bpid_offset |= 0x00004000)) +#define DPAA2_SET_FLE_BMT(fle) (((fle)->fin_bpid_offset |= 0x00008000)) +#define DPAA2_SET_FD_COMPOUND_FMT(fd) \ + ((fd)->simple.bpid_offset |= (uint32_t)1 << 28) +#define DPAA2_GET_FD_ADDR(fd) \ +(((((uint64_t)((fd)->simple.addr_hi)) << 32) + (fd)->simple.addr_lo)) + +#define DPAA2_GET_FD_LEN(fd) ((fd)->simple.len) +#define DPAA2_GET_FD_BPID(fd) (((fd)->simple.bpid_offset & 0x00003FFF)) +#define DPAA2_GET_FD_IVP(fd) (((fd)->simple.bpid_offset & 0x00004000) >> 14) +#define DPAA2_GET_FD_OFFSET(fd) (((fd)->simple.bpid_offset & 0x0FFF0000) >> 16) +#define DPAA2_GET_FD_FRC(fd) ((fd)->simple.frc) +#define DPAA2_GET_FD_FLC(fd) \ + (((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo) +#define DPAA2_GET_FD_ERR(fd) ((fd)->simple.bpid_offset & 0x000000FF) +#define DPAA2_GET_FLE_OFFSET(fle) (((fle)->fin_bpid_offset & 0x0FFF0000) >> 16) +#define DPAA2_SET_FLE_SG_EXT(fle) ((fle)->fin_bpid_offset |= (uint64_t)1 << 29) +#define DPAA2_IS_SET_FLE_SG_EXT(fle) \ + (((fle)->fin_bpid_offset & ((uint64_t)1 << 29)) ? 1 : 0) + +#define DPAA2_INLINE_MBUF_FROM_BUF(buf, meta_data_size) \ + ((struct rte_mbuf *)((size_t)(buf) - (meta_data_size))) + +#define DPAA2_ASAL_VAL (DPAA2_MBUF_HW_ANNOTATION / 64) + +#define DPAA2_FD_SET_FORMAT(fd, format) do { \ + (fd)->simple.bpid_offset &= 0xCFFFFFFF; \ + (fd)->simple.bpid_offset |= (uint32_t)format << 28; \ +} while (0) +#define DPAA2_FD_GET_FORMAT(fd) (((fd)->simple.bpid_offset >> 28) & 0x3) + +#define DPAA2_SG_SET_FINAL(sg, fin) do { \ + (sg)->fin_bpid_offset &= 0x7FFFFFFF; \ + (sg)->fin_bpid_offset |= (uint32_t)fin << 31; \ +} while (0) +#define DPAA2_SG_IS_FINAL(sg) (!!((sg)->fin_bpid_offset >> 31)) +/* Only Enqueue Error responses will be + * pushed on FQID_ERR of Enqueue FQ + */ +#define DPAA2_EQ_RESP_ERR_FQ 0 +/* All Enqueue responses will be pushed on address + * set with qbman_eq_desc_set_response + */ +#define DPAA2_EQ_RESP_ALWAYS 1 + +/* Various structures representing contiguous memory maps */ +struct dpaa2_memseg { + TAILQ_ENTRY(dpaa2_memseg) next; + char *vaddr; + rte_iova_t iova; + size_t len; +}; + +TAILQ_HEAD(dpaa2_memseg_list, dpaa2_memseg); +extern struct dpaa2_memseg_list rte_dpaa2_memsegs; + +#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA +extern uint8_t dpaa2_virt_mode; +static void *dpaa2_mem_ptov(phys_addr_t paddr) __attribute__((unused)); +/* todo - this is costly, need to write a fast coversion routine */ +static void *dpaa2_mem_ptov(phys_addr_t paddr) +{ + struct dpaa2_memseg *ms; + + if (dpaa2_virt_mode) + return (void *)(size_t)paddr; + + /* Check if the address is already part of the memseg list internally + * maintained by the dpaa2 driver. + */ + TAILQ_FOREACH(ms, &rte_dpaa2_memsegs, next) { + if (paddr >= ms->iova && paddr < + ms->iova + ms->len) + return RTE_PTR_ADD(ms->vaddr, (uintptr_t)(paddr - ms->iova)); + } + + /* If not, Fallback to full memseg list searching */ + return rte_mem_iova2virt(paddr); +} + +static phys_addr_t dpaa2_mem_vtop(uint64_t vaddr) __attribute__((unused)); +static phys_addr_t dpaa2_mem_vtop(uint64_t vaddr) +{ + const struct rte_memseg *memseg; + + if (dpaa2_virt_mode) + return vaddr; + + memseg = rte_mem_virt2memseg((void *)(uintptr_t)vaddr, NULL); + if (memseg) + return memseg->phys_addr + RTE_PTR_DIFF(vaddr, memseg->addr); + return (size_t)NULL; +} + +/** + * When we are using Physical addresses as IO Virtual Addresses, + * Need to call conversion routines dpaa2_mem_vtop & dpaa2_mem_ptov + * wherever required. + * These routines are called with help of below MACRO's + */ + +#define DPAA2_MBUF_VADDR_TO_IOVA(mbuf) ((mbuf)->buf_iova) + +/** + * macro to convert Virtual address to IOVA + */ +#define DPAA2_VADDR_TO_IOVA(_vaddr) dpaa2_mem_vtop((size_t)(_vaddr)) + +/** + * macro to convert IOVA to Virtual address + */ +#define DPAA2_IOVA_TO_VADDR(_iova) dpaa2_mem_ptov((size_t)(_iova)) + +/** + * macro to convert modify the memory containing IOVA to Virtual address + */ +#define DPAA2_MODIFY_IOVA_TO_VADDR(_mem, _type) \ + {_mem = (_type)(dpaa2_mem_ptov((size_t)(_mem))); } + +#else /* RTE_LIBRTE_DPAA2_USE_PHYS_IOVA */ + +#define DPAA2_MBUF_VADDR_TO_IOVA(mbuf) ((mbuf)->buf_addr) +#define DPAA2_VADDR_TO_IOVA(_vaddr) (_vaddr) +#define DPAA2_IOVA_TO_VADDR(_iova) (_iova) +#define DPAA2_MODIFY_IOVA_TO_VADDR(_mem, _type) + +#endif /* RTE_LIBRTE_DPAA2_USE_PHYS_IOVA */ + +static inline +int check_swp_active_dqs(uint16_t dpio_index) +{ + if (rte_global_active_dqs_list[dpio_index].global_active_dqs != NULL) + return 1; + return 0; +} + +static inline +void clear_swp_active_dqs(uint16_t dpio_index) +{ + rte_global_active_dqs_list[dpio_index].global_active_dqs = NULL; +} + +static inline +struct qbman_result *get_swp_active_dqs(uint16_t dpio_index) +{ + return rte_global_active_dqs_list[dpio_index].global_active_dqs; +} + +static inline +void set_swp_active_dqs(uint16_t dpio_index, struct qbman_result *dqs) +{ + rte_global_active_dqs_list[dpio_index].global_active_dqs = dqs; +} +struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void); +void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp); +int dpaa2_dpbp_supported(void); + +struct dpaa2_dpci_dev *rte_dpaa2_alloc_dpci_dev(void); +void rte_dpaa2_free_dpci_dev(struct dpaa2_dpci_dev *dpci); + +#endif |