Hi Wei,
> -----Original Message----- > From: Huang, Wei <wei.hu...@intel.com> > Sent: Thursday, June 09, 2022 15:37 > To: dev@dpdk.org; tho...@monjalon.net; nipun.gu...@nxp.com; > hemant.agra...@nxp.com > Cc: sta...@dpdk.org; Xu, Rosen <rosen...@intel.com>; Zhang, Tianfei > <tianfei.zh...@intel.com>; Zhang, Qi Z <qi.z.zh...@intel.com>; Huang, Wei > <wei.hu...@intel.com> > Subject: [PATCH v7 4/5] raw/ifpga: add HE-MEM AFU driver > > HE-MEM is one of the host exerciser modules in OFS FPGA, which is used to > test local memory with built-in traffic generator. > This driver initialize the module and report test result. > > Signed-off-by: Wei Huang <wei.hu...@intel.com> > Acked-by: Tianfei Zhang <tianfei.zh...@intel.com> > --- > v2: move source files to ifpga and rename > --- > drivers/raw/ifpga/afu_pmd_he_mem.c | 183 > +++++++++++++++++++++++++++++++++++++ > drivers/raw/ifpga/afu_pmd_he_mem.h | 46 ++++++++++ > drivers/raw/ifpga/meson.build | 2 +- > drivers/raw/ifpga/rte_pmd_afu.h | 7 ++ > 4 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 > drivers/raw/ifpga/afu_pmd_he_mem.c > create mode 100644 drivers/raw/ifpga/afu_pmd_he_mem.h > > diff --git a/drivers/raw/ifpga/afu_pmd_he_mem.c > b/drivers/raw/ifpga/afu_pmd_he_mem.c > new file mode 100644 > index 0000000..0f57a03 > --- /dev/null > +++ b/drivers/raw/ifpga/afu_pmd_he_mem.c > @@ -0,0 +1,183 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#include <errno.h> > +#include <stdio.h> > +#include <stdint.h> > +#include <stdlib.h> > +#include <unistd.h> > +#include <fcntl.h> > +#include <poll.h> > +#include <sys/eventfd.h> > +#include <sys/ioctl.h> > + > +#include <rte_eal.h> > +#include <rte_malloc.h> > +#include <rte_memcpy.h> > +#include <rte_io.h> > +#include <rte_vfio.h> > +#include <rte_bus_pci.h> > +#include <rte_bus_ifpga.h> > +#include <rte_rawdev.h> > + > +#include "afu_pmd_core.h" > +#include "afu_pmd_he_mem.h" > + > +static int he_mem_tg_test(struct afu_rawdev *dev) { > + struct he_mem_tg_priv *priv = NULL; > + struct rte_pmd_afu_he_mem_tg_cfg *cfg = NULL; > + struct he_mem_tg_ctx *ctx = NULL; > + uint64_t value = 0x12345678; > + uint64_t cap = 0; > + uint64_t channel_mask = 0; > + int i, t = 0; > + > + if (!dev) > + return -EINVAL; > + > + priv = (struct he_mem_tg_priv *)dev->priv; > + if (!priv) > + return -ENOENT; > + > + cfg = &priv->he_mem_tg_cfg; > + ctx = &priv->he_mem_tg_ctx; > + > + IFPGA_RAWDEV_PMD_DEBUG("Channel mask: 0x%x", cfg- > >channel_mask); > + > + rte_write64(value, ctx->addr + MEM_TG_SCRATCHPAD); > + cap = rte_read64(ctx->addr + MEM_TG_SCRATCHPAD); > + IFPGA_RAWDEV_PMD_DEBUG("Scratchpad value: 0x%"PRIx64, cap); > + if (cap != value) { > + IFPGA_RAWDEV_PMD_ERR("Test scratchpad register failed"); > + return -EIO; > + } > + > + cap = rte_read64(ctx->addr + MEM_TG_CTRL); > + IFPGA_RAWDEV_PMD_DEBUG("Capability: 0x%"PRIx64, cap); > + > + channel_mask = cfg->channel_mask & cap; > + /* start traffic generators */ > + rte_write64(channel_mask, ctx->addr + MEM_TG_CTRL); > + > + /* check test status */ > + while (t < MEM_TG_TIMEOUT_MS) { > + value = rte_read64(ctx->addr + MEM_TG_STAT); > + for (i = 0; i < NUM_MEM_TG_CHANNELS; i++) { > + if (channel_mask & (1 << i)) { > + if (TGACTIVE(value, i)) > + continue; > + printf("TG channel %d test %s\n", i, > + TGPASS(value, i) ? "pass" : > + TGTIMEOUT(value, i) ? "timeout" : > + TGFAIL(value, i) ? "fail" : "error"); > + channel_mask &= ~(1 << i); > + } > + } > + if (!channel_mask) > + break; > + rte_delay_ms(MEM_TG_POLL_INTERVAL_MS); > + t += MEM_TG_POLL_INTERVAL_MS; > + } > + > + if (channel_mask) { > + IFPGA_RAWDEV_PMD_ERR("Timeout 0x%04lx", (unsigned > long)value); > + return channel_mask; > + } > + > + return 0; > +} > + > +static int he_mem_tg_init(struct afu_rawdev *dev) { > + struct he_mem_tg_priv *priv = NULL; > + struct he_mem_tg_ctx *ctx = NULL; > + > + if (!dev) > + return -EINVAL; > + > + priv = (struct he_mem_tg_priv *)dev->priv; > + if (!priv) { > + priv = rte_zmalloc(NULL, sizeof(struct he_mem_tg_priv), 0); > + if (!priv) > + return -ENOMEM; > + dev->priv = priv; > + } > + > + ctx = &priv->he_mem_tg_ctx; > + ctx->addr = (uint8_t *)dev->addr; > + > + return 0; > +} > + > +static int he_mem_tg_config(struct afu_rawdev *dev, void *config, > + size_t config_size) > +{ > + struct he_mem_tg_priv *priv = NULL; > + > + if (!dev || !config || !config_size) > + return -EINVAL; > + > + priv = (struct he_mem_tg_priv *)dev->priv; > + if (!priv) > + return -ENOENT; > + > + if (config_size != sizeof(struct rte_pmd_afu_he_mem_tg_cfg)) > + return -EINVAL; > + > + rte_memcpy(&priv->he_mem_tg_cfg, config, sizeof(priv- > >he_mem_tg_cfg)); > + > + return 0; > +} > + > +static int he_mem_tg_close(struct afu_rawdev *dev) { > + if (!dev) > + return -EINVAL; > + > + rte_free(dev->priv); > + dev->priv = NULL; > + > + return 0; > +} > + > +static int he_mem_tg_dump(struct afu_rawdev *dev, FILE *f) { > + struct he_mem_tg_priv *priv = NULL; > + struct he_mem_tg_ctx *ctx = NULL; > + > + if (!dev) > + return -EINVAL; > + > + priv = (struct he_mem_tg_priv *)dev->priv; > + if (!priv) > + return -ENOENT; > + > + if (!f) > + f = stdout; > + > + ctx = &priv->he_mem_tg_ctx; > + > + fprintf(f, "addr:\t\t%p\n", (void *)ctx->addr); > + > + return 0; > +} > + > +static struct afu_ops he_mem_tg_ops = { > + .init = he_mem_tg_init, > + .config = he_mem_tg_config, > + .start = NULL, > + .stop = NULL, > + .test = he_mem_tg_test, > + .close = he_mem_tg_close, > + .dump = he_mem_tg_dump, > + .reset = NULL > +}; > + > +struct afu_rawdev_drv he_mem_tg_drv = { > + .uuid = { HE_MEM_TG_UUID_L, HE_MEM_TG_UUID_H }, > + .ops = &he_mem_tg_ops > +}; > + > +AFU_PMD_REGISTER(he_mem_tg_drv); > diff --git a/drivers/raw/ifpga/afu_pmd_he_mem.h > b/drivers/raw/ifpga/afu_pmd_he_mem.h > new file mode 100644 > index 0000000..5549687 > --- /dev/null > +++ b/drivers/raw/ifpga/afu_pmd_he_mem.h > @@ -0,0 +1,46 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#ifndef _AFU_PMD_HE_MEM_H_ > +#define _AFU_PMD_HE_MEM_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include "afu_pmd_core.h" > +#include "rte_pmd_afu.h" > + > +#define HE_MEM_TG_UUID_L 0xa3dc5b831f5cecbb #define > HE_MEM_TG_UUID_H > +0x4dadea342c7848cb > + > +#define NUM_MEM_TG_CHANNELS 4 > +#define MEM_TG_TIMEOUT_MS 5000 > +#define MEM_TG_POLL_INTERVAL_MS 10 > + > +/* MEM-TG registers definition */ > +#define MEM_TG_SCRATCHPAD 0x28 > +#define MEM_TG_CTRL 0x30 > +#define TGCONTROL(n) (1 << (n)) > +#define MEM_TG_STAT 0x38 > +#define TGSTATUS(v, n) (((v) >> (n << 2)) & 0xf) > +#define TGPASS(v, n) (((v) >> ((n << 2) + 3)) & 0x1) > +#define TGFAIL(v, n) (((v) >> ((n << 2) + 2)) & 0x1) > +#define TGTIMEOUT(v, n) (((v) >> ((n << 2) + 1)) & 0x1) > +#define TGACTIVE(v, n) (((v) >> (n << 2)) & 0x1) > + > +struct he_mem_tg_ctx { > + uint8_t *addr; > +}; > + > +struct he_mem_tg_priv { > + struct rte_pmd_afu_he_mem_tg_cfg he_mem_tg_cfg; > + struct he_mem_tg_ctx he_mem_tg_ctx; > +}; > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _AFU_PMD_HE_MEM_H_ */ > diff --git a/drivers/raw/ifpga/meson.build b/drivers/raw/ifpga/meson.build > index 629ff8a..dc6941d 100644 > --- a/drivers/raw/ifpga/meson.build > +++ b/drivers/raw/ifpga/meson.build > @@ -14,7 +14,7 @@ deps += ['ethdev', 'rawdev', 'pci', 'bus_pci', 'kvargs', > 'bus_vdev', 'bus_ifpga', 'net', 'net_i40e', 'net_ipn3ke'] > > sources = files('ifpga_rawdev.c', 'rte_pmd_ifpga.c', 'afu_pmd_core.c', > - 'afu_pmd_n3000.c', 'afu_pmd_he_lpbk.c') > + 'afu_pmd_n3000.c', 'afu_pmd_he_lpbk.c', 'afu_pmd_he_mem.c') > > includes += include_directories('base') includes += > include_directories('../../net/ipn3ke') > diff --git a/drivers/raw/ifpga/rte_pmd_afu.h > b/drivers/raw/ifpga/rte_pmd_afu.h index 19b3902..213e854 100644 > --- a/drivers/raw/ifpga/rte_pmd_afu.h > +++ b/drivers/raw/ifpga/rte_pmd_afu.h > @@ -104,6 +104,13 @@ struct rte_pmd_afu_he_lpbk_cfg { > uint32_t freq_mhz; > }; > > +/** > + * HE-MEM-TG AFU configuration data structure. > + */ > +struct rte_pmd_afu_he_mem_tg_cfg { > + uint32_t channel_mask; /* mask of traffic generator channel */ > +}; > + > #ifdef __cplusplus > } > #endif > -- > 1.8.3.1 Reviewed-by: Rosen Xu <rosen...@intel.com>