All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chenbo Xia <chenbo.xia@intel.com>
To: dev@dpdk.org, thomas@monjalon.net, david.marchand@redhat.com
Cc: stephen@networkplumber.org, cunming.liang@intel.com,
	xiuchun.lu@intel.com, miao.li@intel.com, jingjing.wu@intel.com
Subject: [dpdk-dev] [PATCH 6/8] emu/iavf: add emudev operations to fit in emudev framework
Date: Fri, 18 Dec 2020 15:47:34 +0800	[thread overview]
Message-ID: <20201218074736.93999-7-chenbo.xia@intel.com> (raw)
In-Reply-To: <20201218074736.93999-1-chenbo.xia@intel.com>

This patch implements emudev opertions to make emulated iavf
fit into rte_emudev framework. Lifecycle related and device
resource related operations are both implemented.

Signed-off-by: Chenbo Xia <chenbo.xia@intel.com>
Signed-off-by: Xiuchun Lu <xiuchun.lu@intel.com>
---
 drivers/emu/iavf/iavf_emu.c     | 218 ++++++++++++++++++++++++++++++++
 drivers/emu/iavf/rte_iavf_emu.h |  59 +++++++++
 2 files changed, 277 insertions(+)

diff --git a/drivers/emu/iavf/iavf_emu.c b/drivers/emu/iavf/iavf_emu.c
index c1a702d744..9ad371ca98 100644
--- a/drivers/emu/iavf/iavf_emu.c
+++ b/drivers/emu/iavf/iavf_emu.c
@@ -2,7 +2,72 @@
  * Copyright(c) 2020 Intel Corporation
  */
 
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rte_malloc.h>
+#include <rte_emudev.h>
+
 #include "iavf_vfio_user.h"
+#include <iavf_type.h>
+
+static int iavf_emu_dev_start(struct rte_emudev *dev)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+
+	if (iavf->ops != NULL && iavf->ops->device_start != NULL)
+		iavf->ops->device_start(dev);
+
+	return 0;
+}
+
+static void iavf_emu_dev_stop(struct rte_emudev *dev)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+
+	if (iavf->ops != NULL && iavf->ops->device_stop != NULL)
+		iavf->ops->device_stop(dev);
+}
+
+static int iavf_emu_dev_configure(struct rte_emudev *dev,
+		struct rte_emudev_info *dev_conf)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+	struct rte_iavf_emu_config *conf =
+		(struct rte_iavf_emu_config *)dev_conf->dev_priv;
+
+	if (!dev_conf->dev_priv)
+		return -EINVAL;
+
+	/* Currently emulated iavf does not support max_qp_num
+	 * and region num configuration
+	 */
+	if (dev->dev_info.max_qp_num != dev_conf->max_qp_num ||
+		dev->dev_info.region_num != dev_conf->region_num) {
+		EMU_IAVF_LOG(ERR,
+			"Configure max_qp_num/region num not supported\n");
+		return -ENOTSUP;
+	}
+
+	if (conf->qp_num >  RTE_MAX_QUEUES_PER_PORT ||
+		conf->qp_num > RTE_IAVF_EMU_MAX_QP_NUM) {
+		EMU_IAVF_LOG(ERR, "Queue pair num exceeds max\n");
+		return -EINVAL;
+	}
+
+	/* For now, we don't support device configure when data
+	 * path driver is attached
+	 */
+	if (dev->backend_priv) {
+		EMU_IAVF_LOG(ERR, "Configure failed because of "
+			"data path attached\n");
+		return -EPERM;
+	}
+
+	iavf->max_be_lanqp = conf->qp_num;
+	return 0;
+}
 
 static int iavf_emu_dev_close(struct rte_emudev *dev)
 {
@@ -26,6 +91,159 @@ static int iavf_emu_dev_close(struct rte_emudev *dev)
 	return 0;
 }
 
+static int iavf_emu_get_dev_info(struct rte_emudev *dev,
+	rte_emudev_obj_t info)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+	struct rte_iavf_emu_config *conf = (struct rte_iavf_emu_config *)info;
+
+	if (!info)
+		return -EINVAL;
+
+	conf->qp_num = iavf->max_be_lanqp;
+	return 0;
+}
+
+static int iavf_emu_get_mem_table(struct rte_emudev *dev,
+	rte_emudev_mem_table_t *tb)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+
+	*tb = iavf->mem;
+
+	return 0;
+}
+
+static int iavf_emu_get_queue_info(struct rte_emudev *dev, uint32_t queue,
+		struct rte_emudev_q_info *info)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+
+	if (queue < RTE_IAVF_EMU_ADMINQ_NUM) {
+		struct iavf_emu_adminQ *adq = &iavf->adq[queue];
+		uint64_t base, size;
+
+		if (adq->ring_addr_lo == NULL ||
+		    adq->ring_addr_hi == NULL ||
+		    adq->ring_sz == NULL)
+			return -1;
+		base = RTE_IAVF_EMU_32_TO_64(*adq->ring_addr_hi,
+			*adq->ring_addr_lo);
+		size = *adq->ring_sz;
+		info->base = base;
+		info->size = size;
+		info->doorbell_id = queue;
+		/* RX AdminQ should have IRQ vector 0 */
+		info->irq_vector = queue - 1;
+	} else {
+		info->base = 0;
+		info->size = 0;
+		info->doorbell_id = queue;
+		info->irq_vector = -1;
+	}
+
+	return 0;
+}
+
+static int iavf_emu_get_irq_info(struct rte_emudev *dev, uint32_t vector,
+		struct rte_emudev_irq_info *info)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+	struct iavf_emu_intr *intr = iavf->intr;
+	struct iavf_emu_intr_info *intr_info = &intr->info[vector];
+
+	if (vector >= intr->intr_num)
+		return -EINVAL;
+
+	info->eventfd = intr_info->fd;
+	info->enable = intr_info->enable;
+	info->vector = vector;
+
+	return 0;
+}
+
+static int iavf_emu_get_db_info(struct rte_emudev *dev, uint32_t doorbell,
+		struct rte_emudev_db_info *info)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+
+	if (doorbell < RTE_IAVF_EMU_ADMINQ_NUM) {
+		struct iavf_emu_adminQ *adq = &iavf->adq[doorbell];
+
+		info->data.mem.base = (uint64_t)adq->doorbell;
+		info->data.mem.size = adq->db_size;
+	} else {
+		struct iavf_emu_lanQ *lanq =
+			&iavf->lanq[doorbell - RTE_IAVF_EMU_ADMINQ_NUM];
+
+		info->data.mem.base = (uint64_t)lanq->doorbell;
+		info->data.mem.size = lanq->db_size;
+	}
+
+	info->flag |= RTE_EMUDEV_DB_MEM;
+	info->id = doorbell;
+
+	return 0;
+}
+
+static int iavf_emu_subs_ev(struct rte_emudev *dev,
+	rte_emudev_event_chnl_t ev_chnl)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+
+	iavf->ops = (struct rte_iavf_emu_notify_ops *)ev_chnl;
+
+	return 0;
+}
+
+static int iavf_emu_unsubs_ev(struct rte_emudev *dev,
+		rte_emudev_event_chnl_t ev_chnl)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+
+	if ((struct rte_iavf_emu_notify_ops *)ev_chnl == iavf->ops) {
+		iavf->ops = NULL;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int iavf_emu_get_attr(struct rte_emudev *dev, const char *attr_name,
+		rte_emudev_attr_t attr)
+{
+	struct iavf_emudev *iavf = (struct iavf_emudev *)dev->priv_data;
+	struct rte_vfio_user_reg_info *info;
+	int ret = 0;
+
+	info = &iavf->vfio->reg->reg_info[0];
+
+	if (!strcmp(attr_name, RTE_IAVF_EMU_ATTR_ASQ_HEAD))
+		*(uint64_t *)attr = (uint64_t)(uintptr_t)info->base
+			+ IAVF_VF_ATQH1;
+	else if (!strcmp(attr_name, RTE_IAVF_EMU_ATTR_ARQ_HEAD))
+		*(uint64_t *)attr = (uint64_t)(uintptr_t)info->base
+			+ IAVF_VF_ARQH1;
+	else if (!strcmp(attr_name, RTE_IAVF_EMU_ATTR_RESET))
+		*(uint64_t *)attr = (uint64_t)(uintptr_t)info->base
+			+ IAVF_VFGEN_RSTAT;
+	else
+		ret = -EINVAL;
+
+	return ret;
+}
+
 struct rte_emudev_ops emu_iavf_ops = {
+	.dev_start = iavf_emu_dev_start,
+	.dev_stop = iavf_emu_dev_stop,
+	.dev_configure = iavf_emu_dev_configure,
 	.dev_close = iavf_emu_dev_close,
+	.dev_info_get = iavf_emu_get_dev_info,
+	.get_mem_table = iavf_emu_get_mem_table,
+	.get_queue_info = iavf_emu_get_queue_info,
+	.get_irq_info = iavf_emu_get_irq_info,
+	.get_db_info = iavf_emu_get_db_info,
+	.subscribe_event = iavf_emu_subs_ev,
+	.unsubscribe_event = iavf_emu_unsubs_ev,
+	.get_attr = iavf_emu_get_attr,
 };
diff --git a/drivers/emu/iavf/rte_iavf_emu.h b/drivers/emu/iavf/rte_iavf_emu.h
index 6de0989f0b..2abcec97d4 100644
--- a/drivers/emu/iavf/rte_iavf_emu.h
+++ b/drivers/emu/iavf/rte_iavf_emu.h
@@ -6,13 +6,24 @@
 #define _IAVF_EMU_H
 
 #include <stdint.h>
+#include <stddef.h>
+#include <limits.h>
+#include <net/if.h>
+#include <sys/queue.h>
 
+#include <rte_vfio_user.h>
 #include <rte_emudev.h>
 
 #define RTE_IAVF_EMUDEV_TYPE "iavf"
+#define RTE_IAVF_EMU_ATTR_ASQ_HEAD "ASQ_H"
+#define RTE_IAVF_EMU_ATTR_ARQ_HEAD "ARQ_H"
+#define RTE_IAVF_EMU_ATTR_RESET "RESET"
+#define RTE_IAVF_EMU_RESET_IN_PROGRESS 0x00
+#define RTE_IAVF_EMU_RESET_COMPLETED 0x01
 #define RTE_IAVF_EMU_MAX_MEM_REGIONS 256
 #define RTE_IAVF_EMU_MAX_QP_NUM 256
 #define RTE_IAVF_EMU_MAX_INTR 32
+#define RTE_IAVF_EMU_32_TO_64(hi, lo) ((((uint64_t)(hi)) << 32) + (lo))
 
 enum {
 	RTE_IAVF_EMU_ADMINQ_TXQ = 0,
@@ -26,6 +37,11 @@ enum {
 	RTE_IAVF_EMU_MAPPABLE_REG_NUM = 2,
 };
 
+struct rte_iavf_emu_config {
+	/* Maximum queue pair number that data path driver can use */
+	uint32_t qp_num;
+};
+
 struct rte_iavf_emu_mem_reg {
 	uint64_t guest_phys_addr;
 	uint64_t host_user_addr;
@@ -40,6 +56,49 @@ struct rte_iavf_emu_mem {
 	struct rte_iavf_emu_mem_reg regions[RTE_IAVF_EMU_MAX_MEM_REGIONS];
 };
 
+/**
+ * Helper function for data path driver to translate address
+ * of one region
+ *
+ * @param mem
+ *   A pointer to DMA memory table
+ * @param g_addr
+ *   Guest I/O virtual base address of the region
+ * @param[in/out] len
+ *   The length of region
+ * @return
+ *   - >0: Success, process virtual address returned
+ *   - 0: Failure on translation
+ */
+__rte_experimental
+__rte_always_inline uint64_t
+rte_iavf_emu_get_dma_vaddr(struct rte_iavf_emu_mem *mem,
+	uint64_t g_addr, uint64_t *len)
+{
+	struct rte_iavf_emu_mem_reg *reg;
+	uint32_t i;
+
+	for (i = 0; i < mem->region_num; i++) {
+		reg = &mem->regions[i];
+
+		if (g_addr >= reg->guest_phys_addr &&
+			g_addr < reg->guest_phys_addr + reg->size) {
+
+			if (unlikely(*len > reg->guest_phys_addr +
+				 reg->size - g_addr))
+				*len = reg->guest_phys_addr +
+					reg->size - g_addr;
+
+			return g_addr - reg->guest_phys_addr +
+				reg->host_user_addr;
+		}
+	}
+
+	*len = 0;
+
+	return 0;
+}
+
 struct rte_iavf_emu_notify_ops {
 	/* Device is ready */
 	int (*device_ready)(struct rte_emudev *dev);
-- 
2.17.1


  parent reply	other threads:[~2020-12-18  8:04 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-18  7:47 [dpdk-dev] [PATCH 0/8] Introduce emudev library and iavf emudev driver Chenbo Xia
2020-12-18  7:47 ` [dpdk-dev] [PATCH 1/8] lib: introduce emudev library Chenbo Xia
2020-12-18  7:47 ` [dpdk-dev] [PATCH 2/8] doc: add emudev library guide Chenbo Xia
2020-12-18  7:47 ` [dpdk-dev] [PATCH 3/8] emu: introduce emulated iavf driver Chenbo Xia
2020-12-18  7:47 ` [dpdk-dev] [PATCH 4/8] emu/iavf: add vfio-user device register and unregister Chenbo Xia
2021-01-07  7:18   ` Xing, Beilei
2021-01-07  8:41     ` Xia, Chenbo
2020-12-18  7:47 ` [dpdk-dev] [PATCH 5/8] emu/iavf: add resource management and internal logic of iavf Chenbo Xia
2020-12-18  7:47 ` Chenbo Xia [this message]
2020-12-18  7:47 ` [dpdk-dev] [PATCH 7/8] test/emudev: introduce functional test Chenbo Xia
2020-12-18  7:47 ` [dpdk-dev] [PATCH 8/8] doc: update release notes for iavf emudev driver Chenbo Xia
2020-12-18  9:53 ` [dpdk-dev] [PATCH 0/8] Introduce emudev library and " David Marchand
2020-12-19  6:11   ` Xia, Chenbo
2020-12-21  9:52     ` Maxime Coquelin
2020-12-21 12:01       ` Maxime Coquelin
2020-12-22  3:09         ` Xia, Chenbo
2020-12-22  8:48           ` Maxime Coquelin
2020-12-23  5:28             ` Xia, Chenbo
2020-12-19  6:27 ` [dpdk-dev] [PATCH v2 " Chenbo Xia
2020-12-19  6:27   ` [dpdk-dev] [PATCH v2 1/8] lib: introduce emudev library Chenbo Xia
2020-12-19  6:28   ` [dpdk-dev] [PATCH v2 2/8] doc: add emudev library guide Chenbo Xia
2020-12-19  6:28   ` [dpdk-dev] [PATCH v2 3/8] emu: introduce emulated iavf driver Chenbo Xia
2020-12-19  6:28   ` [dpdk-dev] [PATCH v2 4/8] emu/iavf: add vfio-user device register and unregister Chenbo Xia
2021-01-04  6:45     ` Wu, Jingjing
2021-01-05  1:26       ` Xia, Chenbo
2021-01-05 13:41     ` Wu, Jingjing
2021-01-06  7:41       ` Xia, Chenbo
2020-12-19  6:28   ` [dpdk-dev] [PATCH v2 5/8] emu/iavf: add resource management and internal logic of iavf Chenbo Xia
2020-12-29  6:05     ` Wu, Jingjing
2020-12-30  1:59       ` Xia, Chenbo
2020-12-19  6:28   ` [dpdk-dev] [PATCH v2 6/8] emu/iavf: add emudev operations to fit in emudev framework Chenbo Xia
2020-12-19  6:28   ` [dpdk-dev] [PATCH v2 7/8] test/emudev: introduce functional test Chenbo Xia
2020-12-19  6:28   ` [dpdk-dev] [PATCH v2 8/8] doc: update release notes for iavf emudev driver Chenbo Xia
2021-01-13 16:52   ` [dpdk-dev] [PATCH v2 0/8] Introduce emudev library and " Thomas Monjalon
2021-01-14  1:35     ` Xia, Chenbo
2021-01-14  6:25   ` [dpdk-dev] [PATCH v3 " Chenbo Xia
2021-01-14  6:25     ` [dpdk-dev] [PATCH v3 1/8] lib: introduce emudev library Chenbo Xia
2021-01-14  6:25     ` [dpdk-dev] [PATCH v3 2/8] doc: add emudev library guide Chenbo Xia
2021-01-14  6:25     ` [dpdk-dev] [PATCH v3 3/8] emu: introduce emulated iavf driver Chenbo Xia
2021-01-14  6:25     ` [dpdk-dev] [PATCH v3 4/8] emu/iavf: add vfio-user device register and unregister Chenbo Xia
2021-01-14  6:25     ` [dpdk-dev] [PATCH v3 5/8] emu/iavf: add resource management and internal logic of iavf Chenbo Xia
2021-01-14  6:25     ` [dpdk-dev] [PATCH v3 6/8] emu/iavf: add emudev operations to fit in emudev framework Chenbo Xia
2021-01-14  6:25     ` [dpdk-dev] [PATCH v3 7/8] test/emudev: introduce functional test Chenbo Xia
2021-01-14  6:25     ` [dpdk-dev] [PATCH v3 8/8] doc: update release notes for iavf emudev driver Chenbo Xia
2024-02-12 22:49     ` [dpdk-dev] [PATCH v3 0/8] Introduce emudev library and " Stephen Hemminger
2023-06-14 19:47 ` [dpdk-dev] [PATCH " Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201218074736.93999-7-chenbo.xia@intel.com \
    --to=chenbo.xia@intel.com \
    --cc=cunming.liang@intel.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=jingjing.wu@intel.com \
    --cc=miao.li@intel.com \
    --cc=stephen@networkplumber.org \
    --cc=thomas@monjalon.net \
    --cc=xiuchun.lu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.