event/octeontx2: fix build for O1 optimization
[dpdk.git] / drivers / event / octeontx / timvf_probe.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Cavium, Inc
3  */
4
5 #include <rte_eal.h>
6 #include <rte_io.h>
7 #include <rte_pci.h>
8 #include <rte_bus_pci.h>
9
10 #include <octeontx_mbox.h>
11
12 #include "ssovf_evdev.h"
13 #include "timvf_evdev.h"
14
15 #ifndef PCI_VENDOR_ID_CAVIUM
16 #define PCI_VENDOR_ID_CAVIUM                    (0x177D)
17 #endif
18
19 #define PCI_DEVICE_ID_OCTEONTX_TIM_VF           (0xA051)
20 #define TIM_MAX_RINGS                           (64)
21
22 struct timvf_res {
23         uint8_t in_use;
24         uint16_t domain;
25         uint16_t vfid;
26         void *bar0;
27         void *bar2;
28         void *bar4;
29 };
30
31 struct timdev {
32         uint8_t total_timvfs;
33         struct timvf_res rings[TIM_MAX_RINGS];
34 };
35
36 static struct timdev tdev;
37
38 uint8_t
39 timvf_get_ring(void)
40 {
41         uint16_t global_domain = octeontx_get_global_domain();
42         int i;
43
44         for (i = 0; i < tdev.total_timvfs; i++) {
45                 if (tdev.rings[i].domain != global_domain)
46                         continue;
47                 if (tdev.rings[i].in_use)
48                         continue;
49
50                 tdev.rings[i].in_use = true;
51                 return tdev.rings[i].vfid;
52         }
53
54         return UINT8_MAX;
55 }
56
57 void
58 timvf_release_ring(uint8_t tim_ring_id)
59 {
60         uint16_t global_domain = octeontx_get_global_domain();
61         int i;
62
63         for (i = 0; i < tdev.total_timvfs; i++) {
64                 if (tdev.rings[i].domain != global_domain)
65                         continue;
66                 if (tdev.rings[i].vfid == tim_ring_id)
67                         tdev.rings[i].in_use = false;
68         }
69 }
70
71 void*
72 timvf_bar(uint8_t vfid, uint8_t bar)
73 {
74         uint16_t global_domain = octeontx_get_global_domain();
75         struct timvf_res *res = NULL;
76         int i;
77
78         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
79                 return NULL;
80
81         for (i = 0; i < tdev.total_timvfs; i++) {
82                 if (tdev.rings[i].domain != global_domain)
83                         continue;
84                 if (tdev.rings[i].vfid == vfid)
85                         res = &tdev.rings[i];
86
87         }
88
89         if (res == NULL)
90                 return NULL;
91
92         switch (bar) {
93         case 0:
94                 return res->bar0;
95         case 4:
96                 return res->bar4;
97         default:
98                 return NULL;
99         }
100 }
101
102 static int
103 timvf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
104 {
105         uint64_t val;
106         uint16_t vfid;
107         struct timvf_res *res;
108
109         RTE_SET_USED(pci_drv);
110
111         /* For secondary processes, the primary has done all the work */
112         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
113                 return 0;
114
115         if (pci_dev->mem_resource[0].addr == NULL ||
116                         pci_dev->mem_resource[4].addr == NULL) {
117                 timvf_log_err("Empty bars %p %p",
118                                 pci_dev->mem_resource[0].addr,
119                                 pci_dev->mem_resource[4].addr);
120                 return -ENODEV;
121         }
122
123         val = rte_read64((uint8_t *)pci_dev->mem_resource[0].addr +
124                         0x100 /* TIM_VRINGX_BASE */);
125         vfid = (val >> 23) & 0xff;
126         if (vfid >= TIM_MAX_RINGS) {
127                 timvf_log_err("Invalid vfid(%d/%d)", vfid, TIM_MAX_RINGS);
128                 return -EINVAL;
129         }
130
131         res = &tdev.rings[tdev.total_timvfs];
132         res->vfid = vfid;
133         res->bar0 = pci_dev->mem_resource[0].addr;
134         res->bar2 = pci_dev->mem_resource[2].addr;
135         res->bar4 = pci_dev->mem_resource[4].addr;
136         res->domain = (val >> 7) & 0xffff;
137         res->in_use = false;
138         tdev.total_timvfs++;
139         rte_wmb();
140
141         timvf_log_dbg("Domain=%d VFid=%d bar0 %p total_timvfs=%d", res->domain,
142                         res->vfid, pci_dev->mem_resource[0].addr,
143                         tdev.total_timvfs);
144         return 0;
145 }
146
147
148 static const struct rte_pci_id pci_timvf_map[] = {
149         {
150                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
151                                 PCI_DEVICE_ID_OCTEONTX_TIM_VF)
152         },
153         {
154                 .vendor_id = 0,
155         },
156 };
157
158 static struct rte_pci_driver pci_timvf = {
159         .id_table = pci_timvf_map,
160         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
161         .probe = timvf_probe,
162         .remove = NULL,
163 };
164
165 RTE_PMD_REGISTER_PCI(octeontx_timvf, pci_timvf);