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>

Reply via email to