]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/drivers/event/octeontx/timvf_probe.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / dpdk / 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 uint16_t domain;
24 uint16_t vfid;
25 void *bar0;
26 void *bar2;
27 void *bar4;
28 };
29
30 struct timdev {
31 uint8_t total_timvfs;
32 struct timvf_res rings[TIM_MAX_RINGS];
33 };
34
35 static struct timdev tdev;
36
37 int
38 timvf_info(struct timvf_info *tinfo)
39 {
40 int i;
41 struct ssovf_info info;
42
43 if (tinfo == NULL)
44 return -EINVAL;
45
46 if (!tdev.total_timvfs)
47 return -ENODEV;
48
49 if (ssovf_info(&info) < 0)
50 return -EINVAL;
51
52 for (i = 0; i < tdev.total_timvfs; i++) {
53 if (info.domain != tdev.rings[i].domain) {
54 timvf_log_err("GRP error, vfid=%d/%d domain=%d/%d %p",
55 i, tdev.rings[i].vfid,
56 info.domain, tdev.rings[i].domain,
57 tdev.rings[i].bar0);
58 return -EINVAL;
59 }
60 }
61
62 tinfo->total_timvfs = tdev.total_timvfs;
63 tinfo->domain = info.domain;
64 return 0;
65 }
66
67 void*
68 timvf_bar(uint8_t id, uint8_t bar)
69 {
70 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
71 return NULL;
72
73 if (id > tdev.total_timvfs)
74 return NULL;
75
76 switch (bar) {
77 case 0:
78 return tdev.rings[id].bar0;
79 case 4:
80 return tdev.rings[id].bar4;
81 default:
82 return NULL;
83 }
84 }
85
86 static int
87 timvf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
88 {
89 uint64_t val;
90 uint16_t vfid;
91 struct timvf_res *res;
92
93 RTE_SET_USED(pci_drv);
94
95 /* For secondary processes, the primary has done all the work */
96 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
97 return 0;
98
99 if (pci_dev->mem_resource[0].addr == NULL ||
100 pci_dev->mem_resource[4].addr == NULL) {
101 timvf_log_err("Empty bars %p %p",
102 pci_dev->mem_resource[0].addr,
103 pci_dev->mem_resource[4].addr);
104 return -ENODEV;
105 }
106
107 val = rte_read64((uint8_t *)pci_dev->mem_resource[0].addr +
108 0x100 /* TIM_VRINGX_BASE */);
109 vfid = (val >> 23) & 0xff;
110 if (vfid >= TIM_MAX_RINGS) {
111 timvf_log_err("Invalid vfid(%d/%d)", vfid, TIM_MAX_RINGS);
112 return -EINVAL;
113 }
114
115 res = &tdev.rings[tdev.total_timvfs];
116 res->vfid = vfid;
117 res->bar0 = pci_dev->mem_resource[0].addr;
118 res->bar2 = pci_dev->mem_resource[2].addr;
119 res->bar4 = pci_dev->mem_resource[4].addr;
120 res->domain = (val >> 7) & 0xffff;
121 tdev.total_timvfs++;
122 rte_wmb();
123
124 timvf_log_dbg("Domain=%d VFid=%d bar0 %p total_timvfs=%d", res->domain,
125 res->vfid, pci_dev->mem_resource[0].addr,
126 tdev.total_timvfs);
127 return 0;
128 }
129
130
131 static const struct rte_pci_id pci_timvf_map[] = {
132 {
133 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
134 PCI_DEVICE_ID_OCTEONTX_TIM_VF)
135 },
136 {
137 .vendor_id = 0,
138 },
139 };
140
141 static struct rte_pci_driver pci_timvf = {
142 .id_table = pci_timvf_map,
143 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
144 .probe = timvf_probe,
145 .remove = NULL,
146 };
147
148 RTE_PMD_REGISTER_PCI(octeontx_timvf, pci_timvf);