1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
8 #include <rte_bus_pci.h>
10 #include <rte_lcore.h>
11 #include <rte_mempool.h>
14 #include <rte_common.h>
15 #include <rte_rawdev.h>
16 #include <rte_rawdev_pmd.h>
18 #include "otx2_common.h"
19 #include "otx2_ep_rawdev.h"
20 #include "otx2_ep_vf.h"
22 static const struct rte_pci_id pci_sdp_vf_map[] = {
24 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
25 PCI_DEVID_OCTEONTX2_EP_VF)
32 /* SDP_VF default configuration */
33 const struct sdp_config default_sdp_conf = {
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),
44 .max_oqs = SDP_VF_CFG_IO_QUEUES,
45 .info_ptr = SDP_VF_OQ_INFOPTR_MODE,
46 .refill_threshold = SDP_VF_OQ_REFIL_THRESHOLD,
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,
55 const struct sdp_config*
56 sdp_get_defconf(struct sdp_device *sdp_dev __rte_unused)
58 const struct sdp_config *default_conf = NULL;
60 default_conf = &default_sdp_conf;
66 sdp_vfdev_exit(struct rte_rawdev *rawdev)
68 struct sdp_device *sdpvf;
69 uint32_t rawdev_queues, q;
71 otx2_info("%s:", __func__);
73 sdpvf = (struct sdp_device *)rawdev->dev_private;
75 sdpvf->fn_list.disable_io_queues(sdpvf);
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);
84 otx2_info("Num OQs:%d freed", sdpvf->num_oqs);
86 /* Free the oqbuf_pool */
87 rte_mempool_free(sdpvf->enqdeq_mpool);
88 sdpvf->enqdeq_mpool = NULL;
90 otx2_info("Enqdeq_mpool free done");
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);
99 otx2_sdp_dbg("Num IQs:%d freed", sdpvf->num_iqs);
105 sdp_chip_specific_setup(struct sdp_device *sdpvf)
107 struct rte_pci_device *pdev = sdpvf->pci_dev;
108 uint32_t dev_id = pdev->id.device_id;
112 case PCI_DEVID_OCTEONTX2_EP_VF:
113 sdpvf->chip_id = PCI_DEVID_OCTEONTX2_EP_VF;
114 ret = sdp_vf_setup_device(sdpvf);
118 otx2_err("Unsupported device");
123 otx2_info("SDP dev_id[%d]", dev_id);
128 /* SDP VF device initialization */
130 sdp_vfdev_init(struct sdp_device *sdpvf)
132 uint32_t rawdev_queues, q;
134 if (sdp_chip_specific_setup(sdpvf)) {
135 otx2_err("Chip specific setup failed");
139 if (sdpvf->fn_list.setup_device_regs(sdpvf)) {
140 otx2_err("Failed to configure device registers");
144 rawdev_queues = (uint32_t)(sdpvf->sriov_info.rings_per_vf);
146 /* Rawdev queues setup for enqueue/dequeue */
147 for (q = 0; q < rawdev_queues; q++) {
148 if (sdp_setup_iqs(sdpvf, q)) {
149 otx2_err("Failed to setup IQs");
153 otx2_info("Total[%d] IQs setup", sdpvf->num_iqs);
155 for (q = 0; q < rawdev_queues; q++) {
156 if (sdp_setup_oqs(sdpvf, q)) {
157 otx2_err("Failed to setup OQs");
161 otx2_info("Total [%d] OQs setup", sdpvf->num_oqs);
163 /* Enable IQ/OQ for this device */
164 sdpvf->fn_list.enable_io_queues(sdpvf);
166 /* Send OQ desc credits for OQs, credits are always
167 * sent after the OQs are enabled.
169 for (q = 0; q < rawdev_queues; q++) {
170 rte_write32(sdpvf->droq[q]->nb_desc,
171 sdpvf->droq[q]->pkts_credit_reg);
174 otx2_info("OQ[%d] dbells [%d]", q,
175 rte_read32(sdpvf->droq[q]->pkts_credit_reg));
180 otx2_info("SDP Device is Ready");
186 /* Free the allocated OQs */
187 for (q = 0; q < sdpvf->num_oqs; q++)
188 sdp_delete_oqs(sdpvf, q);
191 /* Free the allocated IQs */
192 for (q = 0; q < sdpvf->num_iqs; q++)
193 sdp_delete_iqs(sdpvf, q);
200 sdp_rawdev_start(struct rte_rawdev *dev)
208 sdp_rawdev_stop(struct rte_rawdev *dev)
214 sdp_rawdev_close(struct rte_rawdev *dev)
217 ret = sdp_vfdev_exit(dev);
219 otx2_err(" SDP_EP rawdev exit error");
227 sdp_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config)
229 struct sdp_rawdev_info *app_info = (struct sdp_rawdev_info *)config;
230 struct sdp_device *sdpvf;
232 if (app_info == NULL) {
233 otx2_err("Application config info [NULL]");
237 sdpvf = (struct sdp_device *)dev->dev_private;
239 sdpvf->conf = app_info->app_conf;
240 sdpvf->enqdeq_mpool = app_info->enqdeq_mpool;
242 sdp_vfdev_init(sdpvf);
248 /* SDP VF endpoint rawdev ops */
249 static const struct rte_rawdev_ops sdp_rawdev_ops = {
250 .dev_configure = sdp_rawdev_configure,
251 .dev_start = sdp_rawdev_start,
252 .dev_stop = sdp_rawdev_stop,
253 .dev_close = sdp_rawdev_close,
254 .enqueue_bufs = sdp_rawdev_enqueue,
255 .dequeue_bufs = sdp_rawdev_dequeue,
256 .dev_selftest = sdp_rawdev_selftest,
260 otx2_sdp_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
261 struct rte_pci_device *pci_dev)
263 char name[RTE_RAWDEV_NAME_MAX_LEN];
264 struct sdp_device *sdpvf = NULL;
265 struct rte_rawdev *sdp_rawdev;
268 /* Single process support */
269 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
272 if (pci_dev->mem_resource[0].addr)
273 otx2_info("SDP_EP BAR0 is mapped:");
275 otx2_err("SDP_EP: Failed to map device BARs");
276 otx2_err("BAR0 %p\n BAR2 %p",
277 pci_dev->mem_resource[0].addr,
278 pci_dev->mem_resource[2].addr);
282 memset(name, 0, sizeof(name));
283 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
284 pci_dev->addr.bus, pci_dev->addr.devid,
285 pci_dev->addr.function);
287 /* Allocate rawdev pmd */
288 sdp_rawdev = rte_rawdev_pmd_allocate(name,
289 sizeof(struct sdp_device),
292 if (sdp_rawdev == NULL) {
293 otx2_err("SDP_EP VF rawdev allocation failed");
297 sdp_rawdev->dev_ops = &sdp_rawdev_ops;
298 sdp_rawdev->device = &pci_dev->device;
299 sdp_rawdev->driver_name = pci_dev->driver->driver.name;
301 sdpvf = (struct sdp_device *)sdp_rawdev->dev_private;
302 sdpvf->hw_addr = pci_dev->mem_resource[0].addr;
303 sdpvf->pci_dev = pci_dev;
305 /* Discover the VF number being probed */
306 vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
307 (pci_dev->addr.function & 0x7);
310 sdpvf->vf_num = vf_id;
312 otx2_info("SDP_EP VF[%d] probe done", vf_id);
318 otx2_sdp_rawdev_remove(struct rte_pci_device *pci_dev)
320 char name[RTE_RAWDEV_NAME_MAX_LEN];
321 struct rte_rawdev *rawdev;
322 struct sdp_device *sdpvf;
324 /* Single process support */
325 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
328 if (pci_dev == NULL) {
329 otx2_err("SDP_EP:invalid pci_dev!");
334 memset(name, 0, sizeof(name));
335 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
336 pci_dev->addr.bus, pci_dev->addr.devid,
337 pci_dev->addr.function);
339 rawdev = rte_rawdev_pmd_get_named_dev(name);
340 if (rawdev == NULL) {
341 otx2_err("SDP_EP: invalid device name (%s)", name);
345 sdpvf = (struct sdp_device *)rawdev->dev_private;
346 otx2_info("Removing SDP_EP VF[%d] ", sdpvf->vf_num);
348 /* rte_rawdev_close is called by pmd_release */
349 return rte_rawdev_pmd_release(rawdev);
352 static struct rte_pci_driver rte_sdp_rawdev_pmd = {
353 .id_table = pci_sdp_vf_map,
354 .drv_flags = (RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA),
355 .probe = otx2_sdp_rawdev_probe,
356 .remove = otx2_sdp_rawdev_remove,
359 RTE_PMD_REGISTER_PCI(sdp_rawdev_pci_driver, rte_sdp_rawdev_pmd);
360 RTE_PMD_REGISTER_PCI_TABLE(sdp_rawdev_pci_driver, pci_sdp_vf_map);
361 RTE_PMD_REGISTER_KMOD_DEP(sdp_rawdev_pci_driver, "vfio-pci");