raw/ifpga/base: get board info
[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
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         info->phys_addr = afu_info->region[info->index].phys_addr;
80
81         return 0;
82 }
83
84 static int ifpga_acc_read(struct opae_accelerator *acc, unsigned int region_idx,
85                           u64 offset, unsigned int byte, void *data)
86 {
87         struct ifpga_afu_info *afu_info = acc->data;
88         struct opae_reg_region *region;
89
90         if (!afu_info)
91                 return -EINVAL;
92
93         if (offset + byte <= offset)
94                 return -EINVAL;
95
96         if (region_idx >= afu_info->num_regions)
97                 return -EINVAL;
98
99         region = &afu_info->region[region_idx];
100         if (offset + byte > region->len)
101                 return -EINVAL;
102
103         switch (byte) {
104         case 8:
105                 *(u64  *)data = opae_readq(region->addr + offset);
106                 break;
107         case 4:
108                 *(u32 *)data = opae_readl(region->addr + offset);
109                 break;
110         case 2:
111                 *(u16 *)data = opae_readw(region->addr + offset);
112                 break;
113         case 1:
114                 *(u8 *)data = opae_readb(region->addr + offset);
115                 break;
116         default:
117                 return -EINVAL;
118         }
119
120         return 0;
121 }
122
123 static int ifpga_acc_write(struct opae_accelerator *acc,
124                            unsigned int region_idx, u64 offset,
125                            unsigned int byte, void *data)
126 {
127         struct ifpga_afu_info *afu_info = acc->data;
128         struct opae_reg_region *region;
129
130         if (!afu_info)
131                 return -EINVAL;
132
133         if (offset + byte <= offset)
134                 return -EINVAL;
135
136         if (region_idx >= afu_info->num_regions)
137                 return -EINVAL;
138
139         region = &afu_info->region[region_idx];
140         if (offset + byte > region->len)
141                 return -EINVAL;
142
143         /* normal mmio case */
144         switch (byte) {
145         case 8:
146                 opae_writeq(*(u64 *)data, region->addr + offset);
147                 break;
148         case 4:
149                 opae_writel(*(u32 *)data, region->addr + offset);
150                 break;
151         case 2:
152                 opae_writew(*(u16 *)data, region->addr + offset);
153                 break;
154         case 1:
155                 opae_writeb(*(u8 *)data, region->addr + offset);
156                 break;
157         default:
158                 return -EINVAL;
159         }
160
161         return 0;
162 }
163
164 struct opae_accelerator_ops ifpga_acc_ops = {
165         .read = ifpga_acc_read,
166         .write = ifpga_acc_write,
167         .set_irq = ifpga_acc_set_irq,
168         .get_info = ifpga_acc_get_info,
169         .get_region_info = ifpga_acc_get_region_info,
170         .get_uuid = ifpga_acc_get_uuid,
171 };
172
173 /* Bridge APIs */
174 static int ifpga_br_reset(struct opae_bridge *br)
175 {
176         struct ifpga_port_hw *port = br->data;
177
178         return fpga_port_reset(port);
179 }
180
181 struct opae_bridge_ops ifpga_br_ops = {
182         .reset = ifpga_br_reset,
183 };
184
185 /* Manager APIs */
186 static int ifpga_mgr_flash(struct opae_manager *mgr, int id, const char *buf,
187                            u32 size, u64 *status)
188 {
189         struct ifpga_fme_hw *fme = mgr->data;
190         struct ifpga_hw *hw = fme->parent;
191
192         return ifpga_pr(hw, id, buf, size, status);
193 }
194
195 static int ifpga_mgr_get_eth_group_region_info(struct opae_manager *mgr,
196                 struct opae_eth_group_region_info *info)
197 {
198         struct ifpga_fme_hw *fme = mgr->data;
199
200         if (info->group_id >= MAX_ETH_GROUP_DEVICES)
201                 return -EINVAL;
202
203         info->phys_addr = fme->eth_group_region[info->group_id].phys_addr;
204         info->addr = fme->eth_group_region[info->group_id].addr;
205         info->len = fme->eth_group_region[info->group_id].len;
206
207         info->mem_idx = fme->nums_acc_region + info->group_id;
208
209         return 0;
210 }
211
212 static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
213                 struct opae_sensor_info *sensor,
214                 unsigned int *value)
215 {
216         struct ifpga_fme_hw *fme = mgr->data;
217
218         return fme_mgr_get_sensor_value(fme, sensor, value);
219 }
220
221 static int ifpga_mgr_get_board_info(struct opae_manager *mgr,
222                 struct opae_board_info **info)
223 {
224         struct ifpga_fme_hw *fme = mgr->data;
225
226         *info = &fme->board_info;
227
228         return 0;
229 }
230
231 struct opae_manager_ops ifpga_mgr_ops = {
232         .flash = ifpga_mgr_flash,
233         .get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
234         .get_sensor_value = ifpga_mgr_get_sensor_value,
235         .get_board_info = ifpga_mgr_get_board_info,
236 };
237
238 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
239                 void *buf, int size)
240 {
241         struct ifpga_fme_hw *fme = mgr->data;
242
243         return fme_mgr_read_mac_rom(fme, offset, buf, size);
244 }
245
246 static int ifpga_mgr_write_mac_rom(struct opae_manager *mgr, int offset,
247                 void *buf, int size)
248 {
249         struct ifpga_fme_hw *fme = mgr->data;
250
251         return fme_mgr_write_mac_rom(fme, offset, buf, size);
252 }
253
254 static int ifpga_mgr_get_eth_group_nums(struct opae_manager *mgr)
255 {
256         struct ifpga_fme_hw *fme = mgr->data;
257
258         return fme_mgr_get_eth_group_nums(fme);
259 }
260
261 static int ifpga_mgr_get_eth_group_info(struct opae_manager *mgr,
262                 u8 group_id, struct opae_eth_group_info *info)
263 {
264         struct ifpga_fme_hw *fme = mgr->data;
265
266         return fme_mgr_get_eth_group_info(fme, group_id, info);
267 }
268
269 static int ifpga_mgr_eth_group_reg_read(struct opae_manager *mgr, u8 group_id,
270                 u8 type, u8 index, u16 addr, u32 *data)
271 {
272         struct ifpga_fme_hw *fme = mgr->data;
273
274         return fme_mgr_eth_group_read_reg(fme, group_id,
275                         type, index, addr, data);
276 }
277
278 static int ifpga_mgr_eth_group_reg_write(struct opae_manager *mgr, u8 group_id,
279                 u8 type, u8 index, u16 addr, u32 data)
280 {
281         struct ifpga_fme_hw *fme = mgr->data;
282
283         return fme_mgr_eth_group_write_reg(fme, group_id,
284                         type, index, addr, data);
285 }
286
287 static int ifpga_mgr_get_retimer_info(struct opae_manager *mgr,
288                 struct opae_retimer_info *info)
289 {
290         struct ifpga_fme_hw *fme = mgr->data;
291
292         return fme_mgr_get_retimer_info(fme, info);
293 }
294
295 static int ifpga_mgr_get_retimer_status(struct opae_manager *mgr,
296                 struct opae_retimer_status *status)
297 {
298         struct ifpga_fme_hw *fme = mgr->data;
299
300         return fme_mgr_get_retimer_status(fme, status);
301 }
302
303 /* Network APIs in FME */
304 struct opae_manager_networking_ops ifpga_mgr_network_ops = {
305         .read_mac_rom = ifpga_mgr_read_mac_rom,
306         .write_mac_rom = ifpga_mgr_write_mac_rom,
307         .get_eth_group_nums = ifpga_mgr_get_eth_group_nums,
308         .get_eth_group_info = ifpga_mgr_get_eth_group_info,
309         .eth_group_reg_read = ifpga_mgr_eth_group_reg_read,
310         .eth_group_reg_write = ifpga_mgr_eth_group_reg_write,
311         .get_retimer_info = ifpga_mgr_get_retimer_info,
312         .get_retimer_status = ifpga_mgr_get_retimer_status,
313 };
314
315 /* Adapter APIs */
316 static int ifpga_adapter_enumerate(struct opae_adapter *adapter)
317 {
318         struct ifpga_hw *hw = malloc(sizeof(*hw));
319
320         if (hw) {
321                 opae_memset(hw, 0, sizeof(*hw));
322                 hw->pci_data = adapter->data;
323                 hw->adapter = adapter;
324                 if (ifpga_bus_enumerate(hw))
325                         goto error;
326                 return ifpga_bus_init(hw);
327         }
328
329 error:
330         return -ENOMEM;
331 }
332
333 struct opae_adapter_ops ifpga_adapter_ops = {
334         .enumerate = ifpga_adapter_enumerate,
335 };
336
337 /**
338  *  ifpga_pr - do the partial reconfiguration for a given port device
339  *  @hw: pointer to the HW structure
340  *  @port_id: the port device id
341  *  @buffer: the buffer of the bitstream
342  *  @size: the size of the bitstream
343  *  @status: hardware status including PR error code if return -EIO.
344  *
345  *  @return
346  *   - 0: Success, partial reconfiguration finished.
347  *   - <0: Error code returned in partial reconfiguration.
348  **/
349 int ifpga_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size,
350              u64 *status)
351 {
352         if (!is_valid_port_id(hw, port_id))
353                 return -ENODEV;
354
355         return do_pr(hw, port_id, buffer, size, status);
356 }
357
358 int ifpga_get_prop(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
359                    struct feature_prop *prop)
360 {
361         if (!hw || !prop)
362                 return -EINVAL;
363
364         switch (fiu_id) {
365         case FEATURE_FIU_ID_FME:
366                 return fme_get_prop(&hw->fme, prop);
367         case FEATURE_FIU_ID_PORT:
368                 if (!is_valid_port_id(hw, port_id))
369                         return -ENODEV;
370                 return port_get_prop(&hw->port[port_id], prop);
371         }
372
373         return -ENOENT;
374 }
375
376 int ifpga_set_prop(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
377                    struct feature_prop *prop)
378 {
379         if (!hw || !prop)
380                 return -EINVAL;
381
382         switch (fiu_id) {
383         case FEATURE_FIU_ID_FME:
384                 return fme_set_prop(&hw->fme, prop);
385         case FEATURE_FIU_ID_PORT:
386                 if (!is_valid_port_id(hw, port_id))
387                         return -ENODEV;
388                 return port_set_prop(&hw->port[port_id], prop);
389         }
390
391         return -ENOENT;
392 }
393
394 int ifpga_set_irq(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
395                   u32 feature_id, void *irq_set)
396 {
397         if (!hw || !irq_set)
398                 return -EINVAL;
399
400         switch (fiu_id) {
401         case FEATURE_FIU_ID_FME:
402                 return fme_set_irq(&hw->fme, feature_id, irq_set);
403         case FEATURE_FIU_ID_PORT:
404                 if (!is_valid_port_id(hw, port_id))
405                         return -ENODEV;
406                 return port_set_irq(&hw->port[port_id], feature_id, irq_set);
407         }
408
409         return -ENOENT;
410 }