1
2
3
4#include <string.h>
5#include <unistd.h>
6
7#include <rte_bus.h>
8#include <rte_bus_pci.h>
9#include <rte_eal.h>
10#include <rte_lcore.h>
11#include <rte_mempool.h>
12#include <rte_pci.h>
13
14#include <rte_common.h>
15#include <rte_rawdev.h>
16#include <rte_rawdev_pmd.h>
17
18#include "otx2_common.h"
19#include "otx2_ep_rawdev.h"
20#include "otx2_ep_vf.h"
21
22static const struct rte_pci_id pci_sdp_vf_map[] = {
23 {
24 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
25 PCI_DEVID_OCTEONTX2_EP_VF)
26 },
27 {
28 .vendor_id = 0,
29 },
30};
31
32
33const struct sdp_config default_sdp_conf = {
34
35 .iq = {
36 .max_iqs = SDP_VF_CFG_IO_QUEUES,
37 .instr_type = SDP_VF_64BYTE_INSTR,
38 .pending_list_size = (SDP_VF_MAX_IQ_DESCRIPTORS *
39 SDP_VF_CFG_IO_QUEUES),
40 },
41
42
43 .oq = {
44 .max_oqs = SDP_VF_CFG_IO_QUEUES,
45 .info_ptr = SDP_VF_OQ_INFOPTR_MODE,
46 .refill_threshold = SDP_VF_OQ_REFIL_THRESHOLD,
47 },
48
49 .num_iqdef_descs = SDP_VF_MAX_IQ_DESCRIPTORS,
50 .num_oqdef_descs = SDP_VF_MAX_OQ_DESCRIPTORS,
51 .oqdef_buf_size = SDP_VF_OQ_BUF_SIZE,
52
53};
54
55const struct sdp_config*
56sdp_get_defconf(struct sdp_device *sdp_dev __rte_unused)
57{
58 const struct sdp_config *default_conf = NULL;
59
60 default_conf = &default_sdp_conf;
61
62 return default_conf;
63}
64
65static int
66sdp_vfdev_exit(struct rte_rawdev *rawdev)
67{
68 struct sdp_device *sdpvf;
69 uint32_t rawdev_queues, q;
70
71 otx2_info("%s:", __func__);
72
73 sdpvf = (struct sdp_device *)rawdev->dev_private;
74
75 sdpvf->fn_list.disable_io_queues(sdpvf);
76
77 rawdev_queues = sdpvf->num_oqs;
78 for (q = 0; q < rawdev_queues; q++) {
79 if (sdp_delete_oqs(sdpvf, q)) {
80 otx2_err("Failed to delete OQ:%d", q);
81 return -ENOMEM;
82 }
83 }
84 otx2_info("Num OQs:%d freed", sdpvf->num_oqs);
85
86
87 rte_mempool_free(sdpvf->enqdeq_mpool);
88 sdpvf->enqdeq_mpool = NULL;
89
90 otx2_info("Enqdeq_mpool free done");
91
92 rawdev_queues = sdpvf->num_iqs;
93 for (q = 0; q < rawdev_queues; q++) {
94 if (sdp_delete_iqs(sdpvf, q)) {
95 otx2_err("Failed to delete IQ:%d", q);
96 return -ENOMEM;
97 }
98 }
99 otx2_sdp_dbg("Num IQs:%d freed", sdpvf->num_iqs);
100
101 return 0;
102}
103
104static int
105sdp_chip_specific_setup(struct sdp_device *sdpvf)
106{
107 struct rte_pci_device *pdev = sdpvf->pci_dev;
108 uint32_t dev_id = pdev->id.device_id;
109 int ret;
110
111 switch (dev_id) {
112 case PCI_DEVID_OCTEONTX2_EP_VF:
113 sdpvf->chip_id = PCI_DEVID_OCTEONTX2_EP_VF;
114 ret = sdp_vf_setup_device(sdpvf);
115
116 break;
117 default:
118 otx2_err("Unsupported device");
119 ret = -EINVAL;
120 }
121
122 if (!ret)
123 otx2_info("SDP dev_id[%d]", dev_id);
124
125 return ret;
126}
127
128
129static int
130sdp_vfdev_init(struct sdp_device *sdpvf)
131{
132 uint32_t rawdev_queues, q;
133
134 if (sdp_chip_specific_setup(sdpvf)) {
135 otx2_err("Chip specific setup failed");
136 goto setup_fail;
137 }
138
139 if (sdpvf->fn_list.setup_device_regs(sdpvf)) {
140 otx2_err("Failed to configure device registers");
141 goto setup_fail;
142 }
143
144 rawdev_queues = (uint32_t)(sdpvf->sriov_info.rings_per_vf);
145
146
147 for (q = 0; q < rawdev_queues; q++) {
148 if (sdp_setup_iqs(sdpvf, q)) {
149 otx2_err("Failed to setup IQs");
150 goto iq_fail;
151 }
152 }
153 otx2_info("Total[%d] IQs setup", sdpvf->num_iqs);
154
155 for (q = 0; q < rawdev_queues; q++) {
156 if (sdp_setup_oqs(sdpvf, q)) {
157 otx2_err("Failed to setup OQs");
158 goto oq_fail;
159 }
160 }
161 otx2_info("Total [%d] OQs setup", sdpvf->num_oqs);
162
163
164 sdpvf->fn_list.enable_io_queues(sdpvf);
165
166
167
168
169 for (q = 0; q < rawdev_queues; q++) {
170 rte_write32(sdpvf->droq[q]->nb_desc,
171 sdpvf->droq[q]->pkts_credit_reg);
172
173 rte_io_mb();
174 otx2_info("OQ[%d] dbells [%d]", q,
175 rte_read32(sdpvf->droq[q]->pkts_credit_reg));
176 }
177
178 rte_wmb();
179
180 otx2_info("SDP Device is Ready");
181
182 return 0;
183
184
185oq_fail:
186
187 for (q = 0; q < sdpvf->num_oqs; q++)
188 sdp_delete_oqs(sdpvf, q);
189
190iq_fail:
191
192 for (q = 0; q < sdpvf->num_iqs; q++)
193 sdp_delete_iqs(sdpvf, q);
194
195setup_fail:
196 return -ENOMEM;
197}
198
199static int
200sdp_rawdev_start(struct rte_rawdev *dev)
201{
202 dev->started = 1;
203
204 return 0;
205}
206
207static void
208sdp_rawdev_stop(struct rte_rawdev *dev)
209{
210 dev->started = 0;
211}
212
213static int
214sdp_rawdev_close(struct rte_rawdev *dev)
215{
216 int ret;
217 ret = sdp_vfdev_exit(dev);
218 if (ret) {
219 otx2_err(" SDP_EP rawdev exit error");
220 return ret;
221 }
222
223 return 0;
224}
225
226static int
227sdp_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config,
228 size_t config_size)
229{
230 struct sdp_rawdev_info *app_info = (struct sdp_rawdev_info *)config;
231 struct sdp_device *sdpvf;
232
233 if (app_info == NULL || config_size != sizeof(*app_info)) {
234 otx2_err("Application config info [NULL] or incorrect size");
235 return -EINVAL;
236 }
237
238 sdpvf = (struct sdp_device *)dev->dev_private;
239
240 sdpvf->conf = app_info->app_conf;
241 sdpvf->enqdeq_mpool = app_info->enqdeq_mpool;
242
243 sdp_vfdev_init(sdpvf);
244
245 return 0;
246
247}
248
249
250static const struct rte_rawdev_ops sdp_rawdev_ops = {
251 .dev_configure = sdp_rawdev_configure,
252 .dev_start = sdp_rawdev_start,
253 .dev_stop = sdp_rawdev_stop,
254 .dev_close = sdp_rawdev_close,
255 .enqueue_bufs = sdp_rawdev_enqueue,
256 .dequeue_bufs = sdp_rawdev_dequeue,
257 .dev_selftest = sdp_rawdev_selftest,
258};
259
260static int
261otx2_sdp_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
262 struct rte_pci_device *pci_dev)
263{
264 char name[RTE_RAWDEV_NAME_MAX_LEN];
265 struct sdp_device *sdpvf = NULL;
266 struct rte_rawdev *sdp_rawdev;
267 uint16_t vf_id;
268
269
270 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
271 return 0;
272
273 if (pci_dev->mem_resource[0].addr)
274 otx2_info("SDP_EP BAR0 is mapped:");
275 else {
276 otx2_err("SDP_EP: Failed to map device BARs");
277 otx2_err("BAR0 %p\n BAR2 %p",
278 pci_dev->mem_resource[0].addr,
279 pci_dev->mem_resource[2].addr);
280 return -ENODEV;
281 }
282
283 memset(name, 0, sizeof(name));
284 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
285 pci_dev->addr.bus, pci_dev->addr.devid,
286 pci_dev->addr.function);
287
288
289 sdp_rawdev = rte_rawdev_pmd_allocate(name,
290 sizeof(struct sdp_device),
291 rte_socket_id());
292
293 if (sdp_rawdev == NULL) {
294 otx2_err("SDP_EP VF rawdev allocation failed");
295 return -ENOMEM;
296 }
297
298 sdp_rawdev->dev_ops = &sdp_rawdev_ops;
299 sdp_rawdev->device = &pci_dev->device;
300 sdp_rawdev->driver_name = pci_dev->driver->driver.name;
301
302 sdpvf = (struct sdp_device *)sdp_rawdev->dev_private;
303 sdpvf->hw_addr = pci_dev->mem_resource[0].addr;
304 sdpvf->pci_dev = pci_dev;
305
306
307 vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
308 (pci_dev->addr.function & 0x7);
309
310 vf_id -= 1;
311 sdpvf->vf_num = vf_id;
312
313 otx2_info("SDP_EP VF[%d] probe done", vf_id);
314
315 return 0;
316}
317
318static int
319otx2_sdp_rawdev_remove(struct rte_pci_device *pci_dev)
320{
321 char name[RTE_RAWDEV_NAME_MAX_LEN];
322 struct rte_rawdev *rawdev;
323 struct sdp_device *sdpvf;
324
325
326 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
327 return 0;
328
329 if (pci_dev == NULL) {
330 otx2_err("SDP_EP:invalid pci_dev!");
331 return -EINVAL;
332 }
333
334
335 memset(name, 0, sizeof(name));
336 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
337 pci_dev->addr.bus, pci_dev->addr.devid,
338 pci_dev->addr.function);
339
340 rawdev = rte_rawdev_pmd_get_named_dev(name);
341 if (rawdev == NULL) {
342 otx2_err("SDP_EP: invalid device name (%s)", name);
343 return -EINVAL;
344 }
345
346 sdpvf = (struct sdp_device *)rawdev->dev_private;
347 otx2_info("Removing SDP_EP VF[%d] ", sdpvf->vf_num);
348
349
350 return rte_rawdev_pmd_release(rawdev);
351}
352
353static struct rte_pci_driver rte_sdp_rawdev_pmd = {
354 .id_table = pci_sdp_vf_map,
355 .drv_flags = (RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA),
356 .probe = otx2_sdp_rawdev_probe,
357 .remove = otx2_sdp_rawdev_remove,
358};
359
360RTE_PMD_REGISTER_PCI(sdp_rawdev_pci_driver, rte_sdp_rawdev_pmd);
361RTE_PMD_REGISTER_PCI_TABLE(sdp_rawdev_pci_driver, pci_sdp_vf_map);
362RTE_PMD_REGISTER_KMOD_DEP(sdp_rawdev_pci_driver, "vfio-pci");
363