raw/octeontx2_ep: add device configuration
[dpdk.git] / drivers / raw / octeontx2_ep / otx2_ep_rawdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
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
22 static 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 /* SDP_VF default configuration */
33 const struct sdp_config default_sdp_conf = {
34         /* IQ attributes */
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         /* OQ attributes */
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
55 const struct sdp_config*
56 sdp_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
65 static int
66 sdp_chip_specific_setup(struct sdp_device *sdpvf)
67 {
68         struct rte_pci_device *pdev = sdpvf->pci_dev;
69         uint32_t dev_id = pdev->id.device_id;
70         int ret;
71
72         switch (dev_id) {
73         case PCI_DEVID_OCTEONTX2_EP_VF:
74                 sdpvf->chip_id = PCI_DEVID_OCTEONTX2_EP_VF;
75                 ret = sdp_vf_setup_device(sdpvf);
76
77                 break;
78         default:
79                 otx2_err("Unsupported device");
80                 ret = -EINVAL;
81         }
82
83         if (!ret)
84                 otx2_info("SDP dev_id[%d]", dev_id);
85
86         return ret;
87 }
88
89 /* SDP VF device initialization */
90 static int
91 sdp_vfdev_init(struct sdp_device *sdpvf)
92 {
93         uint32_t rawdev_queues, q;
94
95         if (sdp_chip_specific_setup(sdpvf)) {
96                 otx2_err("Chip specific setup failed");
97                 goto setup_fail;
98         }
99
100         if (sdpvf->fn_list.setup_device_regs(sdpvf)) {
101                 otx2_err("Failed to configure device registers");
102                 goto setup_fail;
103         }
104
105         rawdev_queues = (uint32_t)(sdpvf->sriov_info.rings_per_vf);
106
107         /* Rawdev queues setup for enqueue/dequeue */
108         for (q = 0; q < rawdev_queues; q++) {
109                 if (sdp_setup_iqs(sdpvf, q)) {
110                         otx2_err("Failed to setup IQs");
111                         goto iq_fail;
112                 }
113         }
114         otx2_info("Total[%d] IQs setup", sdpvf->num_iqs);
115
116         for (q = 0; q < rawdev_queues; q++) {
117                 if (sdp_setup_oqs(sdpvf, q)) {
118                         otx2_err("Failed to setup OQs");
119                         goto oq_fail;
120                 }
121         }
122         otx2_info("Total [%d] OQs setup", sdpvf->num_oqs);
123
124         /* Enable IQ/OQ for this device */
125         sdpvf->fn_list.enable_io_queues(sdpvf);
126
127         /* Send OQ desc credits for OQs, credits are always
128          * sent after the OQs are enabled.
129          */
130         for (q = 0; q < rawdev_queues; q++) {
131                 rte_write32(sdpvf->droq[q]->nb_desc,
132                             sdpvf->droq[q]->pkts_credit_reg);
133
134                 rte_io_mb();
135                 otx2_info("OQ[%d] dbells [%d]", q,
136                 rte_read32(sdpvf->droq[q]->pkts_credit_reg));
137         }
138
139         rte_wmb();
140
141         otx2_info("SDP Device is Ready");
142
143         return 0;
144
145 oq_fail:
146 iq_fail:
147 setup_fail:
148         return -ENOMEM;
149 }
150
151 static int
152 sdp_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config)
153 {
154         struct sdp_rawdev_info *app_info = (struct sdp_rawdev_info *)config;
155         struct sdp_device *sdpvf;
156
157         if (app_info == NULL) {
158                 otx2_err("Application config info [NULL]");
159                 return -EINVAL;
160         }
161
162         sdpvf = (struct sdp_device *)dev->dev_private;
163
164         sdpvf->conf = app_info->app_conf;
165         sdpvf->enqdeq_mpool = app_info->enqdeq_mpool;
166
167         sdp_vfdev_init(sdpvf);
168
169         return 0;
170
171 }
172
173 /* SDP VF endpoint rawdev ops */
174 static const struct rte_rawdev_ops sdp_rawdev_ops = {
175         .dev_configure  = sdp_rawdev_configure,
176 };
177
178 static int
179 otx2_sdp_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
180                       struct rte_pci_device *pci_dev)
181 {
182         char name[RTE_RAWDEV_NAME_MAX_LEN];
183         struct sdp_device *sdpvf = NULL;
184         struct rte_rawdev *sdp_rawdev;
185         uint16_t vf_id;
186
187         /* Single process support */
188         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
189                 return 0;
190
191         if (pci_dev->mem_resource[0].addr)
192                 otx2_info("SDP_EP BAR0 is mapped:");
193         else {
194                 otx2_err("SDP_EP: Failed to map device BARs");
195                 otx2_err("BAR0 %p\n BAR2 %p",
196                         pci_dev->mem_resource[0].addr,
197                         pci_dev->mem_resource[2].addr);
198                 return -ENODEV;
199         }
200
201         memset(name, 0, sizeof(name));
202         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
203                  pci_dev->addr.bus, pci_dev->addr.devid,
204                  pci_dev->addr.function);
205
206         /* Allocate rawdev pmd */
207         sdp_rawdev = rte_rawdev_pmd_allocate(name,
208                                              sizeof(struct sdp_device),
209                                              rte_socket_id());
210
211         if (sdp_rawdev == NULL) {
212                 otx2_err("SDP_EP VF rawdev allocation failed");
213                 return -ENOMEM;
214         }
215
216         sdp_rawdev->dev_ops = &sdp_rawdev_ops;
217         sdp_rawdev->device = &pci_dev->device;
218         sdp_rawdev->driver_name = pci_dev->driver->driver.name;
219
220         sdpvf = (struct sdp_device *)sdp_rawdev->dev_private;
221         sdpvf->hw_addr = pci_dev->mem_resource[0].addr;
222         sdpvf->pci_dev = pci_dev;
223
224         /* Discover the VF number being probed */
225         vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
226                  (pci_dev->addr.function & 0x7);
227
228         vf_id -= 1;
229         sdpvf->vf_num = vf_id;
230
231         otx2_info("SDP_EP VF[%d] probe done", vf_id);
232
233         return 0;
234 }
235
236 static int
237 otx2_sdp_rawdev_remove(struct rte_pci_device *pci_dev)
238 {
239         char name[RTE_RAWDEV_NAME_MAX_LEN];
240         struct rte_rawdev *rawdev;
241         struct sdp_device *sdpvf;
242
243         /* Single process support */
244         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
245                 return 0;
246
247         if (pci_dev == NULL) {
248                 otx2_err("SDP_EP:invalid pci_dev!");
249                 return -EINVAL;
250         }
251
252
253         memset(name, 0, sizeof(name));
254         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
255                  pci_dev->addr.bus, pci_dev->addr.devid,
256                  pci_dev->addr.function);
257
258         rawdev = rte_rawdev_pmd_get_named_dev(name);
259         if (rawdev == NULL) {
260                 otx2_err("SDP_EP: invalid device name (%s)", name);
261                 return -EINVAL;
262         }
263
264         sdpvf = (struct sdp_device *)rawdev->dev_private;
265         otx2_info("Removing SDP_EP VF[%d] ", sdpvf->vf_num);
266
267         /* rte_rawdev_close is called by pmd_release */
268         return rte_rawdev_pmd_release(rawdev);
269 }
270
271 static struct rte_pci_driver rte_sdp_rawdev_pmd = {
272         .id_table  = pci_sdp_vf_map,
273         .drv_flags = (RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA),
274         .probe     = otx2_sdp_rawdev_probe,
275         .remove    = otx2_sdp_rawdev_remove,
276 };
277
278 RTE_PMD_REGISTER_PCI(sdp_rawdev_pci_driver, rte_sdp_rawdev_pmd);
279 RTE_PMD_REGISTER_PCI_TABLE(sdp_rawdev_pci_driver, pci_sdp_vf_map);
280 RTE_PMD_REGISTER_KMOD_DEP(sdp_rawdev_pci_driver, "vfio-pci");