xref: /dpdk/drivers/event/octeontx/timvf_probe.c (revision 1f37cb2bb46b1fd403faa7c3bf8884e6a4dfde66)
1fd5baf09SPavan Nikhilesh /* SPDX-License-Identifier: BSD-3-Clause
2fd5baf09SPavan Nikhilesh  * Copyright(c) 2017 Cavium, Inc
3fd5baf09SPavan Nikhilesh  */
4fd5baf09SPavan Nikhilesh 
5fd5baf09SPavan Nikhilesh #include <rte_eal.h>
6fd5baf09SPavan Nikhilesh #include <rte_io.h>
7fd5baf09SPavan Nikhilesh #include <rte_pci.h>
8*1f37cb2bSDavid Marchand #include <bus_pci_driver.h>
9fd5baf09SPavan Nikhilesh 
10fd5baf09SPavan Nikhilesh #include <octeontx_mbox.h>
11fd5baf09SPavan Nikhilesh 
12fd5baf09SPavan Nikhilesh #include "ssovf_evdev.h"
13fd5baf09SPavan Nikhilesh #include "timvf_evdev.h"
14fd5baf09SPavan Nikhilesh 
15fd5baf09SPavan Nikhilesh #ifndef PCI_VENDOR_ID_CAVIUM
16fd5baf09SPavan Nikhilesh #define PCI_VENDOR_ID_CAVIUM			(0x177D)
17fd5baf09SPavan Nikhilesh #endif
18fd5baf09SPavan Nikhilesh 
19fd5baf09SPavan Nikhilesh #define PCI_DEVICE_ID_OCTEONTX_TIM_VF		(0xA051)
20fd5baf09SPavan Nikhilesh #define TIM_MAX_RINGS				(64)
21fd5baf09SPavan Nikhilesh 
22fd5baf09SPavan Nikhilesh struct timvf_res {
233639b4adSPavan Nikhilesh 	uint8_t in_use;
24fd5baf09SPavan Nikhilesh 	uint16_t domain;
25fd5baf09SPavan Nikhilesh 	uint16_t vfid;
26fd5baf09SPavan Nikhilesh 	void *bar0;
27fd5baf09SPavan Nikhilesh 	void *bar2;
28fd5baf09SPavan Nikhilesh 	void *bar4;
29fd5baf09SPavan Nikhilesh };
30fd5baf09SPavan Nikhilesh 
31fd5baf09SPavan Nikhilesh struct timdev {
32fd5baf09SPavan Nikhilesh 	uint8_t total_timvfs;
33fd5baf09SPavan Nikhilesh 	struct timvf_res rings[TIM_MAX_RINGS];
34fd5baf09SPavan Nikhilesh };
35fd5baf09SPavan Nikhilesh 
36fd5baf09SPavan Nikhilesh static struct timdev tdev;
37fd5baf09SPavan Nikhilesh 
383639b4adSPavan Nikhilesh uint8_t
timvf_get_ring(void)393639b4adSPavan Nikhilesh timvf_get_ring(void)
40fd5baf09SPavan Nikhilesh {
413639b4adSPavan Nikhilesh 	uint16_t global_domain = octeontx_get_global_domain();
42fd5baf09SPavan Nikhilesh 	int i;
43fd5baf09SPavan Nikhilesh 
44fd5baf09SPavan Nikhilesh 	for (i = 0; i < tdev.total_timvfs; i++) {
453639b4adSPavan Nikhilesh 		if (tdev.rings[i].domain != global_domain)
463639b4adSPavan Nikhilesh 			continue;
473639b4adSPavan Nikhilesh 		if (tdev.rings[i].in_use)
483639b4adSPavan Nikhilesh 			continue;
493639b4adSPavan Nikhilesh 
503639b4adSPavan Nikhilesh 		tdev.rings[i].in_use = true;
513639b4adSPavan Nikhilesh 		return tdev.rings[i].vfid;
52fd5baf09SPavan Nikhilesh 	}
53fd5baf09SPavan Nikhilesh 
543639b4adSPavan Nikhilesh 	return UINT8_MAX;
553639b4adSPavan Nikhilesh }
563639b4adSPavan Nikhilesh 
573639b4adSPavan Nikhilesh void
timvf_release_ring(uint8_t tim_ring_id)583639b4adSPavan Nikhilesh timvf_release_ring(uint8_t tim_ring_id)
593639b4adSPavan Nikhilesh {
603639b4adSPavan Nikhilesh 	uint16_t global_domain = octeontx_get_global_domain();
613639b4adSPavan Nikhilesh 	int i;
623639b4adSPavan Nikhilesh 
633639b4adSPavan Nikhilesh 	for (i = 0; i < tdev.total_timvfs; i++) {
643639b4adSPavan Nikhilesh 		if (tdev.rings[i].domain != global_domain)
653639b4adSPavan Nikhilesh 			continue;
663639b4adSPavan Nikhilesh 		if (tdev.rings[i].vfid == tim_ring_id)
673639b4adSPavan Nikhilesh 			tdev.rings[i].in_use = false;
683639b4adSPavan Nikhilesh 	}
69fd5baf09SPavan Nikhilesh }
70fd5baf09SPavan Nikhilesh 
71fd5baf09SPavan Nikhilesh void*
timvf_bar(uint8_t vfid,uint8_t bar)723639b4adSPavan Nikhilesh timvf_bar(uint8_t vfid, uint8_t bar)
73fd5baf09SPavan Nikhilesh {
743639b4adSPavan Nikhilesh 	uint16_t global_domain = octeontx_get_global_domain();
753639b4adSPavan Nikhilesh 	struct timvf_res *res = NULL;
763639b4adSPavan Nikhilesh 	int i;
773639b4adSPavan Nikhilesh 
78fd5baf09SPavan Nikhilesh 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
79fd5baf09SPavan Nikhilesh 		return NULL;
80fd5baf09SPavan Nikhilesh 
813639b4adSPavan Nikhilesh 	for (i = 0; i < tdev.total_timvfs; i++) {
823639b4adSPavan Nikhilesh 		if (tdev.rings[i].domain != global_domain)
833639b4adSPavan Nikhilesh 			continue;
843639b4adSPavan Nikhilesh 		if (tdev.rings[i].vfid == vfid)
853639b4adSPavan Nikhilesh 			res = &tdev.rings[i];
863639b4adSPavan Nikhilesh 
873639b4adSPavan Nikhilesh 	}
883639b4adSPavan Nikhilesh 
893639b4adSPavan Nikhilesh 	if (res == NULL)
90fd5baf09SPavan Nikhilesh 		return NULL;
91fd5baf09SPavan Nikhilesh 
92fd5baf09SPavan Nikhilesh 	switch (bar) {
93fd5baf09SPavan Nikhilesh 	case 0:
943639b4adSPavan Nikhilesh 		return res->bar0;
95fd5baf09SPavan Nikhilesh 	case 4:
963639b4adSPavan Nikhilesh 		return res->bar4;
97fd5baf09SPavan Nikhilesh 	default:
98fd5baf09SPavan Nikhilesh 		return NULL;
99fd5baf09SPavan Nikhilesh 	}
100fd5baf09SPavan Nikhilesh }
101fd5baf09SPavan Nikhilesh 
102fd5baf09SPavan Nikhilesh static int
timvf_probe(struct rte_pci_driver * pci_drv,struct rte_pci_device * pci_dev)103fd5baf09SPavan Nikhilesh timvf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
104fd5baf09SPavan Nikhilesh {
105fd5baf09SPavan Nikhilesh 	uint64_t val;
106fd5baf09SPavan Nikhilesh 	uint16_t vfid;
107fd5baf09SPavan Nikhilesh 	struct timvf_res *res;
108fd5baf09SPavan Nikhilesh 
109fd5baf09SPavan Nikhilesh 	RTE_SET_USED(pci_drv);
110fd5baf09SPavan Nikhilesh 
111fd5baf09SPavan Nikhilesh 	/* For secondary processes, the primary has done all the work */
112fd5baf09SPavan Nikhilesh 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
113fd5baf09SPavan Nikhilesh 		return 0;
114fd5baf09SPavan Nikhilesh 
115fd5baf09SPavan Nikhilesh 	if (pci_dev->mem_resource[0].addr == NULL ||
116fd5baf09SPavan Nikhilesh 			pci_dev->mem_resource[4].addr == NULL) {
117fd5baf09SPavan Nikhilesh 		timvf_log_err("Empty bars %p %p",
118fd5baf09SPavan Nikhilesh 				pci_dev->mem_resource[0].addr,
119fd5baf09SPavan Nikhilesh 				pci_dev->mem_resource[4].addr);
120fd5baf09SPavan Nikhilesh 		return -ENODEV;
121fd5baf09SPavan Nikhilesh 	}
122fd5baf09SPavan Nikhilesh 
123fd5baf09SPavan Nikhilesh 	val = rte_read64((uint8_t *)pci_dev->mem_resource[0].addr +
124fd5baf09SPavan Nikhilesh 			0x100 /* TIM_VRINGX_BASE */);
125fd5baf09SPavan Nikhilesh 	vfid = (val >> 23) & 0xff;
126fd5baf09SPavan Nikhilesh 	if (vfid >= TIM_MAX_RINGS) {
127fd5baf09SPavan Nikhilesh 		timvf_log_err("Invalid vfid(%d/%d)", vfid, TIM_MAX_RINGS);
128fd5baf09SPavan Nikhilesh 		return -EINVAL;
129fd5baf09SPavan Nikhilesh 	}
130fd5baf09SPavan Nikhilesh 
131fd5baf09SPavan Nikhilesh 	res = &tdev.rings[tdev.total_timvfs];
132fd5baf09SPavan Nikhilesh 	res->vfid = vfid;
133fd5baf09SPavan Nikhilesh 	res->bar0 = pci_dev->mem_resource[0].addr;
134fd5baf09SPavan Nikhilesh 	res->bar2 = pci_dev->mem_resource[2].addr;
135fd5baf09SPavan Nikhilesh 	res->bar4 = pci_dev->mem_resource[4].addr;
136fd5baf09SPavan Nikhilesh 	res->domain = (val >> 7) & 0xffff;
1373639b4adSPavan Nikhilesh 	res->in_use = false;
138fd5baf09SPavan Nikhilesh 	tdev.total_timvfs++;
139fd5baf09SPavan Nikhilesh 	rte_wmb();
140fd5baf09SPavan Nikhilesh 
141fd5baf09SPavan Nikhilesh 	timvf_log_dbg("Domain=%d VFid=%d bar0 %p total_timvfs=%d", res->domain,
142fd5baf09SPavan Nikhilesh 			res->vfid, pci_dev->mem_resource[0].addr,
143fd5baf09SPavan Nikhilesh 			tdev.total_timvfs);
144fd5baf09SPavan Nikhilesh 	return 0;
145fd5baf09SPavan Nikhilesh }
146fd5baf09SPavan Nikhilesh 
147fd5baf09SPavan Nikhilesh 
148fd5baf09SPavan Nikhilesh static const struct rte_pci_id pci_timvf_map[] = {
149fd5baf09SPavan Nikhilesh 	{
150fd5baf09SPavan Nikhilesh 		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
151fd5baf09SPavan Nikhilesh 				PCI_DEVICE_ID_OCTEONTX_TIM_VF)
152fd5baf09SPavan Nikhilesh 	},
153fd5baf09SPavan Nikhilesh 	{
154fd5baf09SPavan Nikhilesh 		.vendor_id = 0,
155fd5baf09SPavan Nikhilesh 	},
156fd5baf09SPavan Nikhilesh };
157fd5baf09SPavan Nikhilesh 
158fd5baf09SPavan Nikhilesh static struct rte_pci_driver pci_timvf = {
159fd5baf09SPavan Nikhilesh 	.id_table = pci_timvf_map,
160d622cad8SJerin Jacob 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
161fd5baf09SPavan Nikhilesh 	.probe = timvf_probe,
162fd5baf09SPavan Nikhilesh 	.remove = NULL,
163fd5baf09SPavan Nikhilesh };
164fd5baf09SPavan Nikhilesh 
165fd5baf09SPavan Nikhilesh RTE_PMD_REGISTER_PCI(octeontx_timvf, pci_timvf);
166