Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Cavium, Inc
3 : : */
4 : :
5 : : #include <rte_atomic.h>
6 : : #include <rte_common.h>
7 : : #include <rte_eal.h>
8 : : #include <rte_io.h>
9 : : #include <rte_pci.h>
10 : : #include <bus_pci_driver.h>
11 : :
12 : : #include "octeontx_mbox.h"
13 : : #include "ssovf_evdev.h"
14 : :
15 : : #define PCI_VENDOR_ID_CAVIUM 0x177D
16 : : #define PCI_DEVICE_ID_OCTEONTX_SSOGRP_VF 0xA04B
17 : : #define PCI_DEVICE_ID_OCTEONTX_SSOWS_VF 0xA04D
18 : :
19 : : #define SSO_MAX_VHGRP (64)
20 : : #define SSO_MAX_VHWS (32)
21 : :
22 : : struct ssovf_res {
23 : : uint16_t domain;
24 : : uint16_t vfid;
25 : : void *bar0;
26 : : void *bar2;
27 : : };
28 : :
29 : : struct ssowvf_res {
30 : : uint16_t domain;
31 : : uint16_t vfid;
32 : : void *bar0;
33 : : void *bar2;
34 : : void *bar4;
35 : : };
36 : :
37 : : struct ssowvf_identify {
38 : : uint16_t domain;
39 : : uint16_t vfid;
40 : : };
41 : :
42 : : struct ssodev {
43 : : uint8_t total_ssovfs;
44 : : uint8_t total_ssowvfs;
45 : : struct ssovf_res grp[SSO_MAX_VHGRP];
46 : : struct ssowvf_res hws[SSO_MAX_VHWS];
47 : : };
48 : :
49 : : static struct ssodev sdev;
50 : :
51 : : /* Interface functions */
52 : : int
53 : 0 : ssovf_info(struct ssovf_info *info)
54 : : {
55 : : uint8_t i;
56 : : uint16_t domain;
57 : :
58 [ # # # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY || info == NULL)
59 : : return -EINVAL;
60 : :
61 [ # # # # ]: 0 : if (sdev.total_ssovfs == 0 || sdev.total_ssowvfs == 0)
62 : : return -ENODEV;
63 : :
64 : 0 : domain = sdev.grp[0].domain;
65 [ # # ]: 0 : for (i = 0; i < sdev.total_ssovfs; i++) {
66 : : /* Check vfid's are contiguous and belong to same domain */
67 [ # # ]: 0 : if (sdev.grp[i].vfid != i ||
68 [ # # ]: 0 : sdev.grp[i].bar0 == NULL ||
69 [ # # ]: 0 : sdev.grp[i].domain != domain) {
70 : 0 : mbox_log_err("GRP error, vfid=%d/%d domain=%d/%d %p",
71 : : i, sdev.grp[i].vfid,
72 : : domain, sdev.grp[i].domain,
73 : : sdev.grp[i].bar0);
74 : 0 : return -EINVAL;
75 : : }
76 : : }
77 : :
78 [ # # ]: 0 : for (i = 0; i < sdev.total_ssowvfs; i++) {
79 : : /* Check vfid's are contiguous and belong to same domain */
80 [ # # ]: 0 : if (sdev.hws[i].vfid != i ||
81 [ # # ]: 0 : sdev.hws[i].bar0 == NULL ||
82 [ # # ]: 0 : sdev.hws[i].domain != domain) {
83 : 0 : mbox_log_err("HWS error, vfid=%d/%d domain=%d/%d %p",
84 : : i, sdev.hws[i].vfid,
85 : : domain, sdev.hws[i].domain,
86 : : sdev.hws[i].bar0);
87 : 0 : return -EINVAL;
88 : : }
89 : : }
90 : :
91 : 0 : info->domain = domain;
92 : 0 : info->total_ssovfs = sdev.total_ssovfs;
93 : 0 : info->total_ssowvfs = sdev.total_ssowvfs;
94 : 0 : return 0;
95 : : }
96 : :
97 : : void*
98 : 0 : ssovf_bar(enum ssovf_type type, uint8_t id, uint8_t bar)
99 : : {
100 [ # # # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY ||
101 : : type > OCTEONTX_SSO_HWS)
102 : : return NULL;
103 : :
104 [ # # ]: 0 : if (type == OCTEONTX_SSO_GROUP) {
105 [ # # ]: 0 : if (id >= sdev.total_ssovfs)
106 : : return NULL;
107 : : } else {
108 [ # # ]: 0 : if (id >= sdev.total_ssowvfs)
109 : : return NULL;
110 : : }
111 : :
112 [ # # ]: 0 : if (type == OCTEONTX_SSO_GROUP) {
113 [ # # # ]: 0 : switch (bar) {
114 : 0 : case 0:
115 : 0 : return sdev.grp[id].bar0;
116 : 0 : case 2:
117 : 0 : return sdev.grp[id].bar2;
118 : : default:
119 : : return NULL;
120 : : }
121 : : } else {
122 [ # # # # ]: 0 : switch (bar) {
123 : 0 : case 0:
124 : 0 : return sdev.hws[id].bar0;
125 : 0 : case 2:
126 : 0 : return sdev.hws[id].bar2;
127 : 0 : case 4:
128 : 0 : return sdev.hws[id].bar4;
129 : : default:
130 : : return NULL;
131 : : }
132 : : }
133 : : }
134 : :
135 : : /* SSOWVF pcie device aka event port probe */
136 : :
137 : : static int
138 : 0 : ssowvf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
139 : : {
140 : : uint16_t vfid;
141 : : struct ssowvf_res *res;
142 : : struct ssowvf_identify *id;
143 : : uint8_t *ram_mbox_base;
144 : :
145 : : RTE_SET_USED(pci_drv);
146 : :
147 : : /* For secondary processes, the primary has done all the work */
148 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
149 : : return 0;
150 : :
151 [ # # ]: 0 : if (pci_dev->mem_resource[0].addr == NULL ||
152 [ # # ]: 0 : pci_dev->mem_resource[2].addr == NULL ||
153 [ # # ]: 0 : pci_dev->mem_resource[4].addr == NULL) {
154 : 0 : mbox_log_err("Empty bars %p %p %p",
155 : : pci_dev->mem_resource[0].addr,
156 : : pci_dev->mem_resource[2].addr,
157 : : pci_dev->mem_resource[4].addr);
158 : 0 : return -ENODEV;
159 : : }
160 : :
161 [ # # ]: 0 : if (pci_dev->mem_resource[4].len != SSOW_BAR4_LEN) {
162 : 0 : mbox_log_err("Bar4 len mismatch %d != %d",
163 : : SSOW_BAR4_LEN, (int)pci_dev->mem_resource[4].len);
164 : 0 : return -EINVAL;
165 : : }
166 : :
167 : : id = pci_dev->mem_resource[4].addr;
168 : 0 : vfid = id->vfid;
169 [ # # ]: 0 : if (vfid >= SSO_MAX_VHWS) {
170 : 0 : mbox_log_err("Invalid vfid(%d/%d)", vfid, SSO_MAX_VHWS);
171 : 0 : return -EINVAL;
172 : : }
173 : :
174 : 0 : res = &sdev.hws[vfid];
175 : 0 : res->vfid = vfid;
176 : 0 : res->bar0 = pci_dev->mem_resource[0].addr;
177 : 0 : res->bar2 = pci_dev->mem_resource[2].addr;
178 : 0 : res->bar4 = pci_dev->mem_resource[4].addr;
179 : 0 : res->domain = id->domain;
180 : :
181 : 0 : sdev.total_ssowvfs++;
182 [ # # ]: 0 : if (vfid == 0) {
183 : 0 : ram_mbox_base = ssovf_bar(OCTEONTX_SSO_HWS, 0, 4);
184 [ # # ]: 0 : if (octeontx_mbox_set_ram_mbox_base(ram_mbox_base,
185 : 0 : res->domain)) {
186 : 0 : mbox_log_err("Invalid Failed to set ram mbox base");
187 : 0 : return -EINVAL;
188 : : }
189 : : }
190 : :
191 : : rte_wmb();
192 : 0 : mbox_log_dbg("Domain=%d hws=%d total_ssowvfs=%d", res->domain,
193 : : res->vfid, sdev.total_ssowvfs);
194 : 0 : return 0;
195 : : }
196 : :
197 : : static const struct rte_pci_id pci_ssowvf_map[] = {
198 : : {
199 : : RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
200 : : PCI_DEVICE_ID_OCTEONTX_SSOWS_VF)
201 : : },
202 : : {
203 : : .vendor_id = 0,
204 : : },
205 : : };
206 : :
207 : : static struct rte_pci_driver pci_ssowvf = {
208 : : .id_table = pci_ssowvf_map,
209 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
210 : : .probe = ssowvf_probe,
211 : : };
212 : :
213 : 251 : RTE_PMD_REGISTER_PCI(octeontx_ssowvf, pci_ssowvf);
214 : :
215 : : /* SSOVF pcie device aka event queue probe */
216 : :
217 : : static int
218 : 0 : ssovf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
219 : : {
220 : : uint64_t val;
221 : : uint16_t vfid;
222 : : uint8_t *idreg;
223 : : struct ssovf_res *res;
224 : : uint8_t *reg;
225 : :
226 : : RTE_SET_USED(pci_drv);
227 : :
228 : : /* For secondary processes, the primary has done all the work */
229 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
230 : : return 0;
231 : :
232 [ # # ]: 0 : if (pci_dev->mem_resource[0].addr == NULL ||
233 [ # # ]: 0 : pci_dev->mem_resource[2].addr == NULL) {
234 : 0 : mbox_log_err("Empty bars %p %p",
235 : : pci_dev->mem_resource[0].addr,
236 : : pci_dev->mem_resource[2].addr);
237 : 0 : return -ENODEV;
238 : : }
239 : : idreg = pci_dev->mem_resource[0].addr;
240 : : idreg += SSO_VHGRP_AQ_THR;
241 : : val = rte_read64(idreg);
242 : :
243 : : /* Write back the default value of aq_thr */
244 : : rte_write64((1ULL << 33) - 1, idreg);
245 : 0 : vfid = (val >> 16) & 0xffff;
246 [ # # ]: 0 : if (vfid >= SSO_MAX_VHGRP) {
247 : 0 : mbox_log_err("Invalid vfid (%d/%d)", vfid, SSO_MAX_VHGRP);
248 : 0 : return -EINVAL;
249 : : }
250 : :
251 : 0 : res = &sdev.grp[vfid];
252 : 0 : res->vfid = vfid;
253 : 0 : res->bar0 = pci_dev->mem_resource[0].addr;
254 : 0 : res->bar2 = pci_dev->mem_resource[2].addr;
255 : 0 : res->domain = val & 0xffff;
256 : :
257 : 0 : sdev.total_ssovfs++;
258 [ # # ]: 0 : if (vfid == 0) {
259 : 0 : reg = ssovf_bar(OCTEONTX_SSO_GROUP, 0, 0);
260 : 0 : reg += SSO_VHGRP_PF_MBOX(1);
261 [ # # ]: 0 : if (octeontx_mbox_set_reg(reg, res->domain)) {
262 : 0 : mbox_log_err("Invalid Failed to set mbox_reg");
263 : 0 : return -EINVAL;
264 : : }
265 : : }
266 : :
267 : : rte_wmb();
268 : 0 : mbox_log_dbg("Domain=%d group=%d total_ssovfs=%d", res->domain,
269 : : res->vfid, sdev.total_ssovfs);
270 : 0 : return 0;
271 : : }
272 : :
273 : : static const struct rte_pci_id pci_ssovf_map[] = {
274 : : {
275 : : RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
276 : : PCI_DEVICE_ID_OCTEONTX_SSOGRP_VF)
277 : : },
278 : : {
279 : : .vendor_id = 0,
280 : : },
281 : : };
282 : :
283 : : static struct rte_pci_driver pci_ssovf = {
284 : : .id_table = pci_ssovf_map,
285 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
286 : : .probe = ssovf_probe,
287 : : };
288 : :
289 : 251 : RTE_PMD_REGISTER_PCI(octeontx_ssovf, pci_ssovf);
|