1
2
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
62 rte_write64(channel_mask, ctx->addr + MEM_TG_CTRL);
63
64
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