dpdk/drivers/raw/ifpga/afu_pmd_he_mem.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2022 Intel Corporation
   3 */
   4
   5#include <errno.h>
   6#include <stdio.h>
   7#include <stdint.h>
   8#include <stdlib.h>
   9#include <unistd.h>
  10#include <fcntl.h>
  11#include <poll.h>
  12#include <sys/eventfd.h>
  13#include <sys/ioctl.h>
  14
  15#include <rte_eal.h>
  16#include <rte_malloc.h>
  17#include <rte_memcpy.h>
  18#include <rte_io.h>
  19#include <rte_vfio.h>
  20#include <rte_bus_pci.h>
  21#include <rte_bus_ifpga.h>
  22#include <rte_rawdev.h>
  23
  24#include "afu_pmd_core.h"
  25#include "afu_pmd_he_mem.h"
  26
  27static int he_mem_tg_test(struct afu_rawdev *dev)
  28{
  29        struct he_mem_tg_priv *priv = NULL;
  30        struct rte_pmd_afu_he_mem_tg_cfg *cfg = NULL;
  31        struct he_mem_tg_ctx *ctx = NULL;
  32        uint64_t value = 0x12345678;
  33        uint64_t cap = 0;
  34        uint64_t channel_mask = 0;
  35        int i, t = 0;
  36
  37        if (!dev)
  38                return -EINVAL;
  39
  40        priv = (struct he_mem_tg_priv *)dev->priv;
  41        if (!priv)
  42                return -ENOENT;
  43
  44        cfg = &priv->he_mem_tg_cfg;
  45        ctx = &priv->he_mem_tg_ctx;
  46
  47        IFPGA_RAWDEV_PMD_DEBUG("Channel mask: 0x%x", cfg->channel_mask);
  48
  49        rte_write64(value, ctx->addr + MEM_TG_SCRATCHPAD);
  50        cap = rte_read64(ctx->addr + MEM_TG_SCRATCHPAD);
  51        IFPGA_RAWDEV_PMD_DEBUG("Scratchpad value: 0x%"PRIx64, cap);
  52        if (cap != value) {
  53                IFPGA_RAWDEV_PMD_ERR("Test scratchpad register failed");
  54                return -EIO;
  55        }
  56
  57        cap = rte_read64(ctx->addr + MEM_TG_CTRL);
  58        IFPGA_RAWDEV_PMD_DEBUG("Capability: 0x%"PRIx64, cap);
  59
  60        channel_mask = cfg->channel_mask & cap;
  61        /* start traffic generators */
  62        rte_write64(channel_mask, ctx->addr + MEM_TG_CTRL);
  63
  64        /* check test status */
  65        while (t < MEM_TG_TIMEOUT_MS) {
  66                value = rte_read64(ctx->addr + MEM_TG_STAT);
  67                for (i = 0; i < NUM_MEM_TG_CHANNELS; i++) {
  68                        if (channel_mask & (1 << i)) {
  69                                if (TGACTIVE(value, i))
  70                                        continue;
  71                                printf("TG channel %d test %s\n", i,
  72                                        TGPASS(value, i) ? "pass" :
  73                                        TGTIMEOUT(value, i) ? "timeout" :
  74                                        TGFAIL(value, i) ? "fail" : "error");
  75                                channel_mask &= ~(1 << i);
  76                        }
  77                }
  78                if (!channel_mask)
  79                        break;
  80                rte_delay_ms(MEM_TG_POLL_INTERVAL_MS);
  81                t += MEM_TG_POLL_INTERVAL_MS;
  82        }
  83
  84        if (channel_mask) {
  85                IFPGA_RAWDEV_PMD_ERR("Timeout 0x%04lx", (unsigned long)value);
  86                return channel_mask;
  87        }
  88
  89        return 0;
  90}
  91
  92static int he_mem_tg_init(struct afu_rawdev *dev)
  93{
  94        struct he_mem_tg_priv *priv = NULL;
  95        struct he_mem_tg_ctx *ctx = NULL;
  96
  97        if (!dev)
  98                return -EINVAL;
  99
 100        priv = (struct he_mem_tg_priv *)dev->priv;
 101        if (!priv) {
 102                priv = rte_zmalloc(NULL, sizeof(struct he_mem_tg_priv), 0);
 103                if (!priv)
 104                        return -ENOMEM;
 105                dev->priv = priv;
 106        }
 107
 108        ctx = &priv->he_mem_tg_ctx;
 109        ctx->addr = (uint8_t *)dev->addr;
 110
 111        return 0;
 112}
 113
 114static int he_mem_tg_config(struct afu_rawdev *dev, void *config,
 115        size_t config_size)
 116{
 117        struct he_mem_tg_priv *priv = NULL;
 118
 119        if (!dev || !config || !config_size)
 120                return -EINVAL;
 121
 122        priv = (struct he_mem_tg_priv *)dev->priv;
 123        if (!priv)
 124                return -ENOENT;
 125
 126        if (config_size != sizeof(struct rte_pmd_afu_he_mem_tg_cfg))
 127                return -EINVAL;
 128
 129        rte_memcpy(&priv->he_mem_tg_cfg, config, sizeof(priv->he_mem_tg_cfg));
 130
 131        return 0;
 132}
 133
 134static int he_mem_tg_close(struct afu_rawdev *dev)
 135{
 136        if (!dev)
 137                return -EINVAL;
 138
 139        rte_free(dev->priv);
 140        dev->priv = NULL;
 141
 142        return 0;
 143}
 144
 145static int he_mem_tg_dump(struct afu_rawdev *dev, FILE *f)
 146{
 147        struct he_mem_tg_priv *priv = NULL;
 148        struct he_mem_tg_ctx *ctx = NULL;
 149
 150        if (!dev)
 151                return -EINVAL;
 152
 153        priv = (struct he_mem_tg_priv *)dev->priv;
 154        if (!priv)
 155                return -ENOENT;
 156
 157        if (!f)
 158                f = stdout;
 159
 160        ctx = &priv->he_mem_tg_ctx;
 161
 162        fprintf(f, "addr:\t\t%p\n", (void *)ctx->addr);
 163
 164        return 0;
 165}
 166
 167static struct afu_ops he_mem_tg_ops = {
 168        .init = he_mem_tg_init,
 169        .config = he_mem_tg_config,
 170        .start = NULL,
 171        .stop = NULL,
 172        .test = he_mem_tg_test,
 173        .close = he_mem_tg_close,
 174        .dump = he_mem_tg_dump,
 175        .reset = NULL
 176};
 177
 178struct afu_rawdev_drv he_mem_tg_drv = {
 179        .uuid = { HE_MEM_TG_UUID_L, HE_MEM_TG_UUID_H },
 180        .ops = &he_mem_tg_ops
 181};
 182
 183AFU_PMD_REGISTER(he_mem_tg_drv);
 184