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