baseband/fpga_5gnr_fec: add PMD for FPGA 5GNR FEC
[dpdk.git] / drivers / baseband / fpga_5gnr_fec / rte_fpga_5gnr_fec.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4
5 #include <unistd.h>
6
7 #include <rte_common.h>
8 #include <rte_log.h>
9 #include <rte_dev.h>
10 #include <rte_malloc.h>
11 #include <rte_mempool.h>
12 #include <rte_errno.h>
13 #include <rte_pci.h>
14 #include <rte_bus_pci.h>
15 #include <rte_byteorder.h>
16
17 #include <rte_bbdev.h>
18 #include <rte_bbdev_pmd.h>
19
20 #include "fpga_5gnr_fec.h"
21
22 /* 5GNR SW PMD logging ID */
23 static int fpga_5gnr_fec_logtype;
24
25 static int
26 fpga_dev_close(struct rte_bbdev *dev __rte_unused)
27 {
28         return 0;
29 }
30
31 static const struct rte_bbdev_ops fpga_ops = {
32         .close = fpga_dev_close,
33 };
34
35 /* Initialization Function */
36 static void
37 fpga_5gnr_fec_init(struct rte_bbdev *dev, struct rte_pci_driver *drv)
38 {
39         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
40
41         dev->dev_ops = &fpga_ops;
42
43         ((struct fpga_5gnr_fec_device *) dev->data->dev_private)->pf_device =
44                         !strcmp(drv->driver.name,
45                                         RTE_STR(FPGA_5GNR_FEC_PF_DRIVER_NAME));
46         ((struct fpga_5gnr_fec_device *) dev->data->dev_private)->mmio_base =
47                         pci_dev->mem_resource[0].addr;
48
49         rte_bbdev_log_debug(
50                         "Init device %s [%s] @ virtaddr %p phyaddr %#"PRIx64,
51                         dev->device->driver->name, dev->data->name,
52                         (void *)pci_dev->mem_resource[0].addr,
53                         pci_dev->mem_resource[0].phys_addr);
54 }
55
56 static int
57 fpga_5gnr_fec_probe(struct rte_pci_driver *pci_drv,
58         struct rte_pci_device *pci_dev)
59 {
60         struct rte_bbdev *bbdev = NULL;
61         char dev_name[RTE_BBDEV_NAME_MAX_LEN];
62
63         if (pci_dev == NULL) {
64                 rte_bbdev_log(ERR, "NULL PCI device");
65                 return -EINVAL;
66         }
67
68         rte_pci_device_name(&pci_dev->addr, dev_name, sizeof(dev_name));
69
70         /* Allocate memory to be used privately by drivers */
71         bbdev = rte_bbdev_allocate(pci_dev->device.name);
72         if (bbdev == NULL)
73                 return -ENODEV;
74
75         /* allocate device private memory */
76         bbdev->data->dev_private = rte_zmalloc_socket(dev_name,
77                         sizeof(struct fpga_5gnr_fec_device),
78                         RTE_CACHE_LINE_SIZE,
79                         pci_dev->device.numa_node);
80
81         if (bbdev->data->dev_private == NULL) {
82                 rte_bbdev_log(CRIT,
83                                 "Allocate of %zu bytes for device \"%s\" failed",
84                                 sizeof(struct fpga_5gnr_fec_device), dev_name);
85                                 rte_bbdev_release(bbdev);
86                         return -ENOMEM;
87         }
88
89         /* Fill HW specific part of device structure */
90         bbdev->device = &pci_dev->device;
91         bbdev->intr_handle = &pci_dev->intr_handle;
92         bbdev->data->socket_id = pci_dev->device.numa_node;
93
94         /* Invoke FEC FPGA device initialization function */
95         fpga_5gnr_fec_init(bbdev, pci_drv);
96
97         rte_bbdev_log_debug("bbdev id = %u [%s]",
98                         bbdev->data->dev_id, dev_name);
99
100         return 0;
101 }
102
103 static int
104 fpga_5gnr_fec_remove(struct rte_pci_device *pci_dev)
105 {
106         struct rte_bbdev *bbdev;
107         int ret;
108         uint8_t dev_id;
109
110         if (pci_dev == NULL)
111                 return -EINVAL;
112
113         /* Find device */
114         bbdev = rte_bbdev_get_named_dev(pci_dev->device.name);
115         if (bbdev == NULL) {
116                 rte_bbdev_log(CRIT,
117                                 "Couldn't find HW dev \"%s\" to uninitialise it",
118                                 pci_dev->device.name);
119                 return -ENODEV;
120         }
121         dev_id = bbdev->data->dev_id;
122
123         /* free device private memory before close */
124         rte_free(bbdev->data->dev_private);
125
126         /* Close device */
127         ret = rte_bbdev_close(dev_id);
128         if (ret < 0)
129                 rte_bbdev_log(ERR,
130                                 "Device %i failed to close during uninit: %i",
131                                 dev_id, ret);
132
133         /* release bbdev from library */
134         ret = rte_bbdev_release(bbdev);
135         if (ret)
136                 rte_bbdev_log(ERR, "Device %i failed to uninit: %i", dev_id,
137                                 ret);
138
139         rte_bbdev_log_debug("Destroyed bbdev = %u", dev_id);
140
141         return 0;
142 }
143
144 /* FPGA 5GNR FEC PCI PF address map */
145 static struct rte_pci_id pci_id_fpga_5gnr_fec_pf_map[] = {
146         {
147                 RTE_PCI_DEVICE(FPGA_5GNR_FEC_VENDOR_ID,
148                                 FPGA_5GNR_FEC_PF_DEVICE_ID)
149         },
150         {.device_id = 0},
151 };
152
153 static struct rte_pci_driver fpga_5gnr_fec_pci_pf_driver = {
154         .probe = fpga_5gnr_fec_probe,
155         .remove = fpga_5gnr_fec_remove,
156         .id_table = pci_id_fpga_5gnr_fec_pf_map,
157         .drv_flags = RTE_PCI_DRV_NEED_MAPPING
158 };
159
160 /* FPGA 5GNR FEC PCI VF address map */
161 static struct rte_pci_id pci_id_fpga_5gnr_fec_vf_map[] = {
162         {
163                 RTE_PCI_DEVICE(FPGA_5GNR_FEC_VENDOR_ID,
164                                 FPGA_5GNR_FEC_VF_DEVICE_ID)
165         },
166         {.device_id = 0},
167 };
168
169 static struct rte_pci_driver fpga_5gnr_fec_pci_vf_driver = {
170         .probe = fpga_5gnr_fec_probe,
171         .remove = fpga_5gnr_fec_remove,
172         .id_table = pci_id_fpga_5gnr_fec_vf_map,
173         .drv_flags = RTE_PCI_DRV_NEED_MAPPING
174 };
175
176
177 RTE_PMD_REGISTER_PCI(FPGA_5GNR_FEC_PF_DRIVER_NAME, fpga_5gnr_fec_pci_pf_driver);
178 RTE_PMD_REGISTER_PCI_TABLE(FPGA_5GNR_FEC_PF_DRIVER_NAME,
179                 pci_id_fpga_5gnr_fec_pf_map);
180 RTE_PMD_REGISTER_PCI(FPGA_5GNR_FEC_VF_DRIVER_NAME, fpga_5gnr_fec_pci_vf_driver);
181 RTE_PMD_REGISTER_PCI_TABLE(FPGA_5GNR_FEC_VF_DRIVER_NAME,
182                 pci_id_fpga_5gnr_fec_vf_map);
183
184 RTE_INIT(fpga_5gnr_fec_init_log)
185 {
186         fpga_5gnr_fec_logtype = rte_log_register("pmd.bb.fpga_5gnr_fec");
187         if (fpga_5gnr_fec_logtype >= 0)
188 #ifdef RTE_LIBRTE_BBDEV_DEBUG
189                 rte_log_set_level(fpga_5gnr_fec_logtype, RTE_LOG_DEBUG);
190 #else
191                 rte_log_set_level(fpga_5gnr_fec_logtype, RTE_LOG_NOTICE);
192 #endif
193 }