New upstream version 18.08
[deb_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         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);