xref: /dpdk/drivers/raw/ifpga/afu_pmd_he_mem.c (revision 1f37cb2bb46b1fd403faa7c3bf8884e6a4dfde66)
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 <bus_pci_driver.h>
21 #include <bus_ifpga_driver.h>
22 #include <rte_rawdev.h>
23 
24 #include "afu_pmd_core.h"
25 #include "afu_pmd_he_mem.h"
26 
he_mem_tg_test(struct afu_rawdev * dev)27 static 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 
he_mem_tg_init(struct afu_rawdev * dev)92 static 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 
he_mem_tg_config(struct afu_rawdev * dev,void * config,size_t config_size)114 static 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 
he_mem_tg_close(struct afu_rawdev * dev)134 static 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 
he_mem_tg_dump(struct afu_rawdev * dev,FILE * f)145 static 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 
167 static 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 
178 struct 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 
183 AFU_PMD_REGISTER(he_mem_tg_drv);
184