]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/raw/ifpga_rawdev/base/ifpga_api.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / dpdk / drivers / raw / ifpga_rawdev / base / ifpga_api.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
3 */
4
5 #include "ifpga_api.h"
6 #include "ifpga_enumerate.h"
7 #include "ifpga_feature_dev.h"
8
9 #include "opae_hw_api.h"
10
11 /* Accelerator APIs */
12 static int ifpga_acc_get_uuid(struct opae_accelerator *acc,
13 struct uuid *uuid)
14 {
15 struct opae_bridge *br = acc->br;
16 struct ifpga_port_hw *port;
17
18 if (!br || !br->data)
19 return -EINVAL;
20
21 port = br->data;
22
23 return fpga_get_afu_uuid(port, uuid);
24 }
25
26 static int ifpga_acc_set_irq(struct opae_accelerator *acc,
27 u32 start, u32 count, s32 evtfds[])
28 {
29 struct ifpga_afu_info *afu_info = acc->data;
30 struct opae_bridge *br = acc->br;
31 struct ifpga_port_hw *port;
32 struct fpga_uafu_irq_set irq_set;
33
34 if (!br || !br->data)
35 return -EINVAL;
36
37 if (start >= afu_info->num_irqs || start + count > afu_info->num_irqs)
38 return -EINVAL;
39
40 port = br->data;
41
42 irq_set.start = start;
43 irq_set.count = count;
44 irq_set.evtfds = evtfds;
45
46 return ifpga_set_irq(port->parent, FEATURE_FIU_ID_PORT, port->port_id,
47 IFPGA_PORT_FEATURE_ID_UINT, &irq_set);
48 }
49
50 static int ifpga_acc_get_info(struct opae_accelerator *acc,
51 struct opae_acc_info *info)
52 {
53 struct ifpga_afu_info *afu_info = acc->data;
54
55 if (!afu_info)
56 return -ENODEV;
57
58 info->num_regions = afu_info->num_regions;
59 info->num_irqs = afu_info->num_irqs;
60
61 return 0;
62 }
63
64 static int ifpga_acc_get_region_info(struct opae_accelerator *acc,
65 struct opae_acc_region_info *info)
66 {
67 struct ifpga_afu_info *afu_info = acc->data;
68
69 if (!afu_info)
70 return -EINVAL;
71
72 if (info->index >= afu_info->num_regions)
73 return -EINVAL;
74
75 /* always one RW region only for AFU now */
76 info->flags = ACC_REGION_READ | ACC_REGION_WRITE | ACC_REGION_MMIO;
77 info->len = afu_info->region[info->index].len;
78 info->addr = afu_info->region[info->index].addr;
79
80 return 0;
81 }
82
83 static int ifpga_acc_read(struct opae_accelerator *acc, unsigned int region_idx,
84 u64 offset, unsigned int byte, void *data)
85 {
86 struct ifpga_afu_info *afu_info = acc->data;
87 struct opae_reg_region *region;
88
89 if (!afu_info)
90 return -EINVAL;
91
92 if (offset + byte <= offset)
93 return -EINVAL;
94
95 if (region_idx >= afu_info->num_regions)
96 return -EINVAL;
97
98 region = &afu_info->region[region_idx];
99 if (offset + byte > region->len)
100 return -EINVAL;
101
102 switch (byte) {
103 case 8:
104 *(u64 *)data = opae_readq(region->addr + offset);
105 break;
106 case 4:
107 *(u32 *)data = opae_readl(region->addr + offset);
108 break;
109 case 2:
110 *(u16 *)data = opae_readw(region->addr + offset);
111 break;
112 case 1:
113 *(u8 *)data = opae_readb(region->addr + offset);
114 break;
115 default:
116 return -EINVAL;
117 }
118
119 return 0;
120 }
121
122 static int ifpga_acc_write(struct opae_accelerator *acc,
123 unsigned int region_idx, u64 offset,
124 unsigned int byte, void *data)
125 {
126 struct ifpga_afu_info *afu_info = acc->data;
127 struct opae_reg_region *region;
128
129 if (!afu_info)
130 return -EINVAL;
131
132 if (offset + byte <= offset)
133 return -EINVAL;
134
135 if (region_idx >= afu_info->num_regions)
136 return -EINVAL;
137
138 region = &afu_info->region[region_idx];
139 if (offset + byte > region->len)
140 return -EINVAL;
141
142 /* normal mmio case */
143 switch (byte) {
144 case 8:
145 opae_writeq(*(u64 *)data, region->addr + offset);
146 break;
147 case 4:
148 opae_writel(*(u32 *)data, region->addr + offset);
149 break;
150 case 2:
151 opae_writew(*(u16 *)data, region->addr + offset);
152 break;
153 case 1:
154 opae_writeb(*(u8 *)data, region->addr + offset);
155 break;
156 default:
157 return -EINVAL;
158 }
159
160 return 0;
161 }
162
163 struct opae_accelerator_ops ifpga_acc_ops = {
164 .read = ifpga_acc_read,
165 .write = ifpga_acc_write,
166 .set_irq = ifpga_acc_set_irq,
167 .get_info = ifpga_acc_get_info,
168 .get_region_info = ifpga_acc_get_region_info,
169 .get_uuid = ifpga_acc_get_uuid,
170 };
171
172 /* Bridge APIs */
173 static int ifpga_br_reset(struct opae_bridge *br)
174 {
175 struct ifpga_port_hw *port = br->data;
176
177 return fpga_port_reset(port);
178 }
179
180 struct opae_bridge_ops ifpga_br_ops = {
181 .reset = ifpga_br_reset,
182 };
183
184 /* Manager APIs */
185 static int ifpga_mgr_flash(struct opae_manager *mgr, int id, void *buf,
186 u32 size, u64 *status)
187 {
188 struct ifpga_fme_hw *fme = mgr->data;
189 struct ifpga_hw *hw = fme->parent;
190
191 return ifpga_pr(hw, id, buf, size, status);
192 }
193
194 static int ifpga_mgr_get_eth_group_region_info(struct opae_manager *mgr,
195 struct opae_eth_group_region_info *info)
196 {
197 struct ifpga_fme_hw *fme = mgr->data;
198
199 if (info->group_id >= MAX_ETH_GROUP_DEVICES)
200 return -EINVAL;
201
202 info->phys_addr = fme->eth_group_region[info->group_id].phys_addr;
203 info->addr = fme->eth_group_region[info->group_id].addr;
204 info->len = fme->eth_group_region[info->group_id].len;
205
206 info->mem_idx = fme->nums_acc_region + info->group_id;
207
208 return 0;
209 }
210
211 struct opae_manager_ops ifpga_mgr_ops = {
212 .flash = ifpga_mgr_flash,
213 .get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
214 };
215
216 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
217 void *buf, int size)
218 {
219 struct ifpga_fme_hw *fme = mgr->data;
220
221 return fme_mgr_read_mac_rom(fme, offset, buf, size);
222 }
223
224 static int ifpga_mgr_write_mac_rom(struct opae_manager *mgr, int offset,
225 void *buf, int size)
226 {
227 struct ifpga_fme_hw *fme = mgr->data;
228
229 return fme_mgr_write_mac_rom(fme, offset, buf, size);
230 }
231
232 static int ifpga_mgr_get_eth_group_nums(struct opae_manager *mgr)
233 {
234 struct ifpga_fme_hw *fme = mgr->data;
235
236 return fme_mgr_get_eth_group_nums(fme);
237 }
238
239 static int ifpga_mgr_get_eth_group_info(struct opae_manager *mgr,
240 u8 group_id, struct opae_eth_group_info *info)
241 {
242 struct ifpga_fme_hw *fme = mgr->data;
243
244 return fme_mgr_get_eth_group_info(fme, group_id, info);
245 }
246
247 static int ifpga_mgr_eth_group_reg_read(struct opae_manager *mgr, u8 group_id,
248 u8 type, u8 index, u16 addr, u32 *data)
249 {
250 struct ifpga_fme_hw *fme = mgr->data;
251
252 return fme_mgr_eth_group_read_reg(fme, group_id,
253 type, index, addr, data);
254 }
255
256 static int ifpga_mgr_eth_group_reg_write(struct opae_manager *mgr, u8 group_id,
257 u8 type, u8 index, u16 addr, u32 data)
258 {
259 struct ifpga_fme_hw *fme = mgr->data;
260
261 return fme_mgr_eth_group_write_reg(fme, group_id,
262 type, index, addr, data);
263 }
264
265 static int ifpga_mgr_get_retimer_info(struct opae_manager *mgr,
266 struct opae_retimer_info *info)
267 {
268 struct ifpga_fme_hw *fme = mgr->data;
269
270 return fme_mgr_get_retimer_info(fme, info);
271 }
272
273 static int ifpga_mgr_get_retimer_status(struct opae_manager *mgr,
274 struct opae_retimer_status *status)
275 {
276 struct ifpga_fme_hw *fme = mgr->data;
277
278 return fme_mgr_get_retimer_status(fme, status);
279 }
280
281 /* Network APIs in FME */
282 struct opae_manager_networking_ops ifpga_mgr_network_ops = {
283 .read_mac_rom = ifpga_mgr_read_mac_rom,
284 .write_mac_rom = ifpga_mgr_write_mac_rom,
285 .get_eth_group_nums = ifpga_mgr_get_eth_group_nums,
286 .get_eth_group_info = ifpga_mgr_get_eth_group_info,
287 .eth_group_reg_read = ifpga_mgr_eth_group_reg_read,
288 .eth_group_reg_write = ifpga_mgr_eth_group_reg_write,
289 .get_retimer_info = ifpga_mgr_get_retimer_info,
290 .get_retimer_status = ifpga_mgr_get_retimer_status,
291 };
292
293 /* Adapter APIs */
294 static int ifpga_adapter_enumerate(struct opae_adapter *adapter)
295 {
296 struct ifpga_hw *hw = malloc(sizeof(*hw));
297
298 if (hw) {
299 opae_memset(hw, 0, sizeof(*hw));
300 hw->pci_data = adapter->data;
301 hw->adapter = adapter;
302 if (ifpga_bus_enumerate(hw))
303 goto error;
304 return ifpga_bus_init(hw);
305 }
306
307 error:
308 return -ENOMEM;
309 }
310
311 struct opae_adapter_ops ifpga_adapter_ops = {
312 .enumerate = ifpga_adapter_enumerate,
313 };
314
315 /**
316 * ifpga_pr - do the partial reconfiguration for a given port device
317 * @hw: pointer to the HW structure
318 * @port_id: the port device id
319 * @buffer: the buffer of the bitstream
320 * @size: the size of the bitstream
321 * @status: hardware status including PR error code if return -EIO.
322 *
323 * @return
324 * - 0: Success, partial reconfiguration finished.
325 * - <0: Error code returned in partial reconfiguration.
326 **/
327 int ifpga_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size,
328 u64 *status)
329 {
330 if (!is_valid_port_id(hw, port_id))
331 return -ENODEV;
332
333 return do_pr(hw, port_id, buffer, size, status);
334 }
335
336 int ifpga_get_prop(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
337 struct feature_prop *prop)
338 {
339 if (!hw || !prop)
340 return -EINVAL;
341
342 switch (fiu_id) {
343 case FEATURE_FIU_ID_FME:
344 return fme_get_prop(&hw->fme, prop);
345 case FEATURE_FIU_ID_PORT:
346 if (!is_valid_port_id(hw, port_id))
347 return -ENODEV;
348 return port_get_prop(&hw->port[port_id], prop);
349 }
350
351 return -ENOENT;
352 }
353
354 int ifpga_set_prop(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
355 struct feature_prop *prop)
356 {
357 if (!hw || !prop)
358 return -EINVAL;
359
360 switch (fiu_id) {
361 case FEATURE_FIU_ID_FME:
362 return fme_set_prop(&hw->fme, prop);
363 case FEATURE_FIU_ID_PORT:
364 if (!is_valid_port_id(hw, port_id))
365 return -ENODEV;
366 return port_set_prop(&hw->port[port_id], prop);
367 }
368
369 return -ENOENT;
370 }
371
372 int ifpga_set_irq(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
373 u32 feature_id, void *irq_set)
374 {
375 if (!hw || !irq_set)
376 return -EINVAL;
377
378 switch (fiu_id) {
379 case FEATURE_FIU_ID_FME:
380 return fme_set_irq(&hw->fme, feature_id, irq_set);
381 case FEATURE_FIU_ID_PORT:
382 if (!is_valid_port_id(hw, port_id))
383 return -ENODEV;
384 return port_set_irq(&hw->port[port_id], feature_id, irq_set);
385 }
386
387 return -ENOENT;
388 }