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