From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id EB021A055F; Fri, 27 May 2022 07:30:32 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E174C42B78; Fri, 27 May 2022 07:30:12 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id 499A440E25; Fri, 27 May 2022 07:30:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653629410; x=1685165410; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=hkg296gN9n4vO+daMMSlKKww2QfadUHkJBVGkpBXMk0=; b=nttnBo6fsFwbdyTiITMt6seif9NG0XeDrYNt707t48qlYFvUyvGWBNgK bFvy/AOFxvcwEboiOJCf7OD/2smxArkk2cM2FaQ7uErf1MuWKzcrY2U29 mHrs0cwrkwis0XEXRqB2So9kBJmIZWYNDijtKkf4Q/cMSA6uhpgkaI063 mebTCDoWorDEZ4UlKsKh5WSrJgz2UKwO0SJb/v8pygLpGyV/eh55yHwYm hjYfu23BtL9mhSdLOfMUWk5TmYaVuvwX+8eloOSPG3LDOJoemWzolDApy yx90GorL/mvtUg8HxEC8fte6PhhovOIUU25hTsUFicUIAz6TT8gnJHNL7 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10359"; a="299727843" X-IronPort-AV: E=Sophos;i="5.91,254,1647327600"; d="scan'208";a="299727843" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 May 2022 22:30:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,254,1647327600"; d="scan'208";a="746752939" Received: from unknown (HELO zj-fpga-amt.sh.intel.com) ([10.238.175.102]) by orsmga005.jf.intel.com with ESMTP; 26 May 2022 22:30:07 -0700 From: Wei Huang To: dev@dpdk.org, thomas@monjalon.net, nipun.gupta@nxp.com, hemant.agrawal@nxp.com Cc: stable@dpdk.org, rosen.xu@intel.com, tianfei.zhang@intel.com, qi.z.zhang@intel.com, Wei Huang Subject: [PATCH v5 4/5] raw/afu_mf: add HE-MEM AFU driver Date: Fri, 27 May 2022 01:37:03 -0400 Message-Id: <1653629824-4535-5-git-send-email-wei.huang@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1653629824-4535-1-git-send-email-wei.huang@intel.com> References: <1652939560-15786-1-git-send-email-wei.huang@intel.com> <1653629824-4535-1-git-send-email-wei.huang@intel.com> X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org 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 --- drivers/raw/afu_mf/afu_mf_rawdev.c | 3 + drivers/raw/afu_mf/he_mem.c | 181 +++++++++++++++++++++++++++++++++++++ drivers/raw/afu_mf/he_mem.h | 40 ++++++++ drivers/raw/afu_mf/meson.build | 2 +- drivers/raw/afu_mf/rte_pmd_afu.h | 7 ++ 5 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 drivers/raw/afu_mf/he_mem.c create mode 100644 drivers/raw/afu_mf/he_mem.h diff --git a/drivers/raw/afu_mf/afu_mf_rawdev.c b/drivers/raw/afu_mf/afu_mf_rawdev.c index e91eb21..a56f60e 100644 --- a/drivers/raw/afu_mf/afu_mf_rawdev.c +++ b/drivers/raw/afu_mf/afu_mf_rawdev.c @@ -21,6 +21,7 @@ #include "afu_mf_rawdev.h" #include "n3000_afu.h" #include "he_lbk.h" +#include "he_mem.h" #define AFU_MF_PMD_RAWDEV_NAME rawdev_afu_mf @@ -28,6 +29,7 @@ { N3000_AFU_UUID_L, N3000_AFU_UUID_H }, { HE_LBK_UUID_L, HE_LBK_UUID_H }, { HE_MEM_LBK_UUID_L, HE_MEM_LBK_UUID_H }, + { HE_MEM_TG_UUID_L, HE_MEM_TG_UUID_H }, { 0, 0 /* sentinel */ } }; @@ -35,6 +37,7 @@ &n3000_afu_drv, &he_lbk_drv, &he_mem_lbk_drv, + &he_mem_tg_drv, NULL }; diff --git a/drivers/raw/afu_mf/he_mem.c b/drivers/raw/afu_mf/he_mem.c new file mode 100644 index 0000000..ccbb3a8 --- /dev/null +++ b/drivers/raw/afu_mf/he_mem.c @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2022 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "afu_mf_rawdev.h" +#include "he_mem.h" + +static int he_mem_tg_test(struct afu_mf_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; + + AFU_MF_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); + AFU_MF_PMD_DEBUG("Scratchpad value: 0x%"PRIx64, cap); + if (cap != value) { + AFU_MF_PMD_ERR("Test scratchpad register failed"); + return -EIO; + } + + cap = rte_read64(ctx->addr + MEM_TG_CTRL); + AFU_MF_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) { + AFU_MF_PMD_ERR("Timeout 0x%04lx", (unsigned long)value); + return channel_mask; + } + + return 0; +} + +static int he_mem_tg_init(struct afu_mf_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_mf_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_mf_rawdev *dev) +{ + if (!dev) + return -EINVAL; + + rte_free(dev->priv); + dev->priv = NULL; + + return 0; +} + +static int he_mem_tg_dump(struct afu_mf_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_mf_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_mf_drv he_mem_tg_drv = { + .uuid = { HE_MEM_TG_UUID_L, HE_MEM_TG_UUID_H }, + .ops = &he_mem_tg_ops +}; diff --git a/drivers/raw/afu_mf/he_mem.h b/drivers/raw/afu_mf/he_mem.h new file mode 100644 index 0000000..82404b6 --- /dev/null +++ b/drivers/raw/afu_mf/he_mem.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2022 Intel Corporation + */ + +#ifndef _HE_MEM_H_ +#define _HE_MEM_H_ + +#include "afu_mf_rawdev.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 + +extern struct afu_mf_drv he_mem_tg_drv; + +/* 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; +}; + +#endif /* _HE_MEM_H_ */ diff --git a/drivers/raw/afu_mf/meson.build b/drivers/raw/afu_mf/meson.build index a983f53..b53a31b 100644 --- a/drivers/raw/afu_mf/meson.build +++ b/drivers/raw/afu_mf/meson.build @@ -2,6 +2,6 @@ # Copyright 2022 Intel Corporation deps += ['rawdev', 'bus_pci', 'bus_ifpga'] -sources = files('afu_mf_rawdev.c', 'n3000_afu.c', 'he_lbk.c') +sources = files('afu_mf_rawdev.c', 'n3000_afu.c', 'he_lbk.c', 'he_mem.c') headers = files('rte_pmd_afu.h') diff --git a/drivers/raw/afu_mf/rte_pmd_afu.h b/drivers/raw/afu_mf/rte_pmd_afu.h index 658df55..2f92f7e 100644 --- a/drivers/raw/afu_mf/rte_pmd_afu.h +++ b/drivers/raw/afu_mf/rte_pmd_afu.h @@ -104,6 +104,13 @@ struct rte_pmd_afu_he_lbk_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