175177224438e05d18d5f9931cfc6ddc3b8def9a
[dpdk.git] / drivers / raw / octeontx2_dma / otx2_dpi_rawdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <string.h>
6 #include <unistd.h>
7
8 #include <rte_bus.h>
9 #include <rte_bus_pci.h>
10 #include <rte_common.h>
11 #include <rte_eal.h>
12 #include <rte_lcore.h>
13 #include <rte_pci.h>
14 #include <rte_rawdev.h>
15 #include <rte_rawdev_pmd.h>
16
17 #include <otx2_common.h>
18
19 #include "otx2_dpi_rawdev.h"
20
21 static const struct rte_pci_id pci_dma_map[] = {
22         {
23                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
24                                PCI_DEVID_OCTEONTX2_DPI_VF)
25         },
26         {
27                 .vendor_id = 0,
28         },
29 };
30
31 static int
32 otx2_dpi_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
33                       struct rte_pci_device *pci_dev)
34 {
35         char name[RTE_RAWDEV_NAME_MAX_LEN];
36         struct dpi_vf_s *dpivf = NULL;
37         struct rte_rawdev *rawdev;
38         uint16_t vf_id;
39
40         /* For secondary processes, the primary has done all the work */
41         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
42                 return DPI_DMA_QUEUE_SUCCESS;
43
44         if (pci_dev->mem_resource[0].addr == NULL) {
45                 otx2_dpi_dbg("Empty bars %p %p", pci_dev->mem_resource[0].addr,
46                              pci_dev->mem_resource[2].addr);
47                 return -ENODEV;
48         }
49
50         memset(name, 0, sizeof(name));
51         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "DPI:%x:%02x.%x",
52                  pci_dev->addr.bus, pci_dev->addr.devid,
53                  pci_dev->addr.function);
54
55         /* Allocate device structure */
56         rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct dpi_vf_s),
57                                          rte_socket_id());
58         if (rawdev == NULL) {
59                 otx2_err("Rawdev allocation failed");
60                 return -EINVAL;
61         }
62
63         rawdev->device = &pci_dev->device;
64         rawdev->driver_name = pci_dev->driver->driver.name;
65
66         dpivf = rawdev->dev_private;
67         if (dpivf->state != DPI_QUEUE_STOP) {
68                 otx2_dpi_dbg("Device already started!!!");
69                 return -ENODEV;
70         }
71
72         vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
73                  (pci_dev->addr.function & 0x7);
74         vf_id -= 1;
75         dpivf->state = DPI_QUEUE_START;
76         dpivf->vf_id = vf_id;
77         dpivf->vf_bar0 = (uintptr_t)pci_dev->mem_resource[0].addr;
78         dpivf->vf_bar2 = (uintptr_t)pci_dev->mem_resource[2].addr;
79
80         return DPI_DMA_QUEUE_SUCCESS;
81 }
82
83 static int
84 otx2_dpi_rawdev_remove(struct rte_pci_device *pci_dev)
85 {
86         char name[RTE_RAWDEV_NAME_MAX_LEN];
87         struct rte_rawdev *rawdev;
88
89         if (pci_dev == NULL) {
90                 otx2_dpi_dbg("Invalid pci_dev of the device!");
91                 return -EINVAL;
92         }
93
94         memset(name, 0, sizeof(name));
95         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "DPI:%x:%02x.%x",
96                  pci_dev->addr.bus, pci_dev->addr.devid,
97                  pci_dev->addr.function);
98
99         rawdev = rte_rawdev_pmd_get_named_dev(name);
100         if (rawdev == NULL) {
101                 otx2_dpi_dbg("Invalid device name (%s)", name);
102                 return -EINVAL;
103         }
104
105         /* rte_rawdev_close is called by pmd_release */
106         return rte_rawdev_pmd_release(rawdev);
107 }
108
109 static struct rte_pci_driver rte_dpi_rawdev_pmd = {
110         .id_table  = pci_dma_map,
111         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
112         .probe     = otx2_dpi_rawdev_probe,
113         .remove    = otx2_dpi_rawdev_remove,
114 };
115
116 RTE_PMD_REGISTER_PCI(dpi_rawdev_pci_driver, rte_dpi_rawdev_pmd);
117 RTE_PMD_REGISTER_PCI_TABLE(dpi_rawdev_pci_driver, pci_dma_map);
118 RTE_PMD_REGISTER_KMOD_DEP(dpi_rawdev_pci_driver, "vfio-pci");