xref: /dpdk/drivers/raw/ifpga/base/ifpga_api.c (revision 9f3b3a96dec2f4c01cc92a132d763b8887d29e6a)
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 static void ifpga_adapter_destroy(struct opae_adapter *adapter)
334 {
335 	struct ifpga_fme_hw *fme;
336 
337 	if (adapter && adapter->mgr && adapter->mgr->data) {
338 		fme = (struct ifpga_fme_hw *)adapter->mgr->data;
339 		if (fme->parent)
340 			ifpga_bus_uinit(fme->parent);
341 	}
342 }
343 
344 struct opae_adapter_ops ifpga_adapter_ops = {
345 	.enumerate = ifpga_adapter_enumerate,
346 	.destroy = ifpga_adapter_destroy,
347 };
348 
349 /**
350  *  ifpga_pr - do the partial reconfiguration for a given port device
351  *  @hw: pointer to the HW structure
352  *  @port_id: the port device id
353  *  @buffer: the buffer of the bitstream
354  *  @size: the size of the bitstream
355  *  @status: hardware status including PR error code if return -EIO.
356  *
357  *  @return
358  *   - 0: Success, partial reconfiguration finished.
359  *   - <0: Error code returned in partial reconfiguration.
360  **/
361 int ifpga_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size,
362 	     u64 *status)
363 {
364 	if (!is_valid_port_id(hw, port_id))
365 		return -ENODEV;
366 
367 	return do_pr(hw, port_id, buffer, size, status);
368 }
369 
370 int ifpga_get_prop(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
371 		   struct feature_prop *prop)
372 {
373 	if (!hw || !prop)
374 		return -EINVAL;
375 
376 	switch (fiu_id) {
377 	case FEATURE_FIU_ID_FME:
378 		return fme_get_prop(&hw->fme, prop);
379 	case FEATURE_FIU_ID_PORT:
380 		if (!is_valid_port_id(hw, port_id))
381 			return -ENODEV;
382 		return port_get_prop(&hw->port[port_id], prop);
383 	}
384 
385 	return -ENOENT;
386 }
387 
388 int ifpga_set_prop(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
389 		   struct feature_prop *prop)
390 {
391 	if (!hw || !prop)
392 		return -EINVAL;
393 
394 	switch (fiu_id) {
395 	case FEATURE_FIU_ID_FME:
396 		return fme_set_prop(&hw->fme, prop);
397 	case FEATURE_FIU_ID_PORT:
398 		if (!is_valid_port_id(hw, port_id))
399 			return -ENODEV;
400 		return port_set_prop(&hw->port[port_id], prop);
401 	}
402 
403 	return -ENOENT;
404 }
405 
406 int ifpga_set_irq(struct ifpga_hw *hw, u32 fiu_id, u32 port_id,
407 		  u32 feature_id, void *irq_set)
408 {
409 	if (!hw || !irq_set)
410 		return -EINVAL;
411 
412 	switch (fiu_id) {
413 	case FEATURE_FIU_ID_FME:
414 		return fme_set_irq(&hw->fme, feature_id, irq_set);
415 	case FEATURE_FIU_ID_PORT:
416 		if (!is_valid_port_id(hw, port_id))
417 			return -ENODEV;
418 		return port_set_irq(&hw->port[port_id], feature_id, irq_set);
419 	}
420 
421 	return -ENOENT;
422 }
423