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*
sdp_get_defconf(struct sdp_device * sdp_dev __rte_unused)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
sdp_vfdev_exit(struct rte_rawdev * rawdev)66 sdp_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 	/* Free the oqbuf_pool */
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 
104 static int
sdp_chip_specific_setup(struct sdp_device * sdpvf)105 sdp_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 /* SDP VF device initialization */
129 static int
sdp_vfdev_init(struct sdp_device * sdpvf)130 sdp_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 	/* 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");
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 	/* Enable IQ/OQ for this device */
164 	sdpvf->fn_list.enable_io_queues(sdpvf);
165 
166 	/* Send OQ desc credits for OQs, credits are always
167 	 * sent after the OQs are enabled.
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 /* Error handling  */
185 oq_fail:
186 	/* Free the allocated OQs */
187 	for (q = 0; q < sdpvf->num_oqs; q++)
188 		sdp_delete_oqs(sdpvf, q);
189 
190 iq_fail:
191 	/* Free the allocated IQs */
192 	for (q = 0; q < sdpvf->num_iqs; q++)
193 		sdp_delete_iqs(sdpvf, q);
194 
195 setup_fail:
196 	return -ENOMEM;
197 }
198 
199 static int
sdp_rawdev_start(struct rte_rawdev * dev)200 sdp_rawdev_start(struct rte_rawdev *dev)
201 {
202 	dev->started = 1;
203 
204 	return 0;
205 }
206 
207 static void
sdp_rawdev_stop(struct rte_rawdev * dev)208 sdp_rawdev_stop(struct rte_rawdev *dev)
209 {
210 	dev->started = 0;
211 }
212 
213 static int
sdp_rawdev_close(struct rte_rawdev * dev)214 sdp_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 
226 static int
sdp_rawdev_configure(const struct rte_rawdev * dev,rte_rawdev_obj_t config,size_t config_size)227 sdp_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 /* SDP VF endpoint rawdev ops */
250 static 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 
260 static int
otx2_sdp_rawdev_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pci_dev)261 otx2_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 	/* Single process support */
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 	/* Allocate rawdev pmd */
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 	/* Discover the VF number being probed */
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 
318 static int
otx2_sdp_rawdev_remove(struct rte_pci_device * pci_dev)319 otx2_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 	/* Single process support */
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 	/* rte_rawdev_close is called by pmd_release */
350 	return rte_rawdev_pmd_release(rawdev);
351 }
352 
353 static 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 
360 RTE_PMD_REGISTER_PCI(sdp_rawdev_pci_driver, rte_sdp_rawdev_pmd);
361 RTE_PMD_REGISTER_PCI_TABLE(sdp_rawdev_pci_driver, pci_sdp_vf_map);
362 RTE_PMD_REGISTER_KMOD_DEP(sdp_rawdev_pci_driver, "vfio-pci");
363