1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
6 #include "ifpga_enumerate.h"
7 #include "ifpga_feature_dev.h"
9 #include "opae_hw_api.h"
11 /* Accelerator APIs */
12 static int ifpga_acc_get_uuid(struct opae_accelerator
*acc
,
15 struct opae_bridge
*br
= acc
->br
;
16 struct ifpga_port_hw
*port
;
23 return fpga_get_afu_uuid(port
, uuid
);
26 static int ifpga_acc_set_irq(struct opae_accelerator
*acc
,
27 u32 start
, u32 count
, s32 evtfds
[])
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
;
37 if (start
>= afu_info
->num_irqs
|| start
+ count
> afu_info
->num_irqs
)
42 irq_set
.start
= start
;
43 irq_set
.count
= count
;
44 irq_set
.evtfds
= evtfds
;
46 return ifpga_set_irq(port
->parent
, FEATURE_FIU_ID_PORT
, port
->port_id
,
47 IFPGA_PORT_FEATURE_ID_UINT
, &irq_set
);
50 static int ifpga_acc_get_info(struct opae_accelerator
*acc
,
51 struct opae_acc_info
*info
)
53 struct ifpga_afu_info
*afu_info
= acc
->data
;
58 info
->num_regions
= afu_info
->num_regions
;
59 info
->num_irqs
= afu_info
->num_irqs
;
64 static int ifpga_acc_get_region_info(struct opae_accelerator
*acc
,
65 struct opae_acc_region_info
*info
)
67 struct ifpga_afu_info
*afu_info
= acc
->data
;
72 if (info
->index
>= afu_info
->num_regions
)
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
;
83 static int ifpga_acc_read(struct opae_accelerator
*acc
, unsigned int region_idx
,
84 u64 offset
, unsigned int byte
, void *data
)
86 struct ifpga_afu_info
*afu_info
= acc
->data
;
87 struct opae_reg_region
*region
;
92 if (offset
+ byte
<= offset
)
95 if (region_idx
>= afu_info
->num_regions
)
98 region
= &afu_info
->region
[region_idx
];
99 if (offset
+ byte
> region
->len
)
104 *(u64
*)data
= opae_readq(region
->addr
+ offset
);
107 *(u32
*)data
= opae_readl(region
->addr
+ offset
);
110 *(u16
*)data
= opae_readw(region
->addr
+ offset
);
113 *(u8
*)data
= opae_readb(region
->addr
+ offset
);
122 static int ifpga_acc_write(struct opae_accelerator
*acc
,
123 unsigned int region_idx
, u64 offset
,
124 unsigned int byte
, void *data
)
126 struct ifpga_afu_info
*afu_info
= acc
->data
;
127 struct opae_reg_region
*region
;
132 if (offset
+ byte
<= offset
)
135 if (region_idx
>= afu_info
->num_regions
)
138 region
= &afu_info
->region
[region_idx
];
139 if (offset
+ byte
> region
->len
)
142 /* normal mmio case */
145 opae_writeq(*(u64
*)data
, region
->addr
+ offset
);
148 opae_writel(*(u32
*)data
, region
->addr
+ offset
);
151 opae_writew(*(u16
*)data
, region
->addr
+ offset
);
154 opae_writeb(*(u8
*)data
, region
->addr
+ offset
);
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
,
173 static int ifpga_br_reset(struct opae_bridge
*br
)
175 struct ifpga_port_hw
*port
= br
->data
;
177 return fpga_port_reset(port
);
180 struct opae_bridge_ops ifpga_br_ops
= {
181 .reset
= ifpga_br_reset
,
185 static int ifpga_mgr_flash(struct opae_manager
*mgr
, int id
, void *buf
,
186 u32 size
, u64
*status
)
188 struct ifpga_fme_hw
*fme
= mgr
->data
;
189 struct ifpga_hw
*hw
= fme
->parent
;
191 return ifpga_pr(hw
, id
, buf
, size
, status
);
194 static int ifpga_mgr_get_eth_group_region_info(struct opae_manager
*mgr
,
195 struct opae_eth_group_region_info
*info
)
197 struct ifpga_fme_hw
*fme
= mgr
->data
;
199 if (info
->group_id
>= MAX_ETH_GROUP_DEVICES
)
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
;
206 info
->mem_idx
= fme
->nums_acc_region
+ info
->group_id
;
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
,
216 static int ifpga_mgr_read_mac_rom(struct opae_manager
*mgr
, int offset
,
219 struct ifpga_fme_hw
*fme
= mgr
->data
;
221 return fme_mgr_read_mac_rom(fme
, offset
, buf
, size
);
224 static int ifpga_mgr_write_mac_rom(struct opae_manager
*mgr
, int offset
,
227 struct ifpga_fme_hw
*fme
= mgr
->data
;
229 return fme_mgr_write_mac_rom(fme
, offset
, buf
, size
);
232 static int ifpga_mgr_get_eth_group_nums(struct opae_manager
*mgr
)
234 struct ifpga_fme_hw
*fme
= mgr
->data
;
236 return fme_mgr_get_eth_group_nums(fme
);
239 static int ifpga_mgr_get_eth_group_info(struct opae_manager
*mgr
,
240 u8 group_id
, struct opae_eth_group_info
*info
)
242 struct ifpga_fme_hw
*fme
= mgr
->data
;
244 return fme_mgr_get_eth_group_info(fme
, group_id
, info
);
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
)
250 struct ifpga_fme_hw
*fme
= mgr
->data
;
252 return fme_mgr_eth_group_read_reg(fme
, group_id
,
253 type
, index
, addr
, data
);
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
)
259 struct ifpga_fme_hw
*fme
= mgr
->data
;
261 return fme_mgr_eth_group_write_reg(fme
, group_id
,
262 type
, index
, addr
, data
);
265 static int ifpga_mgr_get_retimer_info(struct opae_manager
*mgr
,
266 struct opae_retimer_info
*info
)
268 struct ifpga_fme_hw
*fme
= mgr
->data
;
270 return fme_mgr_get_retimer_info(fme
, info
);
273 static int ifpga_mgr_get_retimer_status(struct opae_manager
*mgr
,
274 struct opae_retimer_status
*status
)
276 struct ifpga_fme_hw
*fme
= mgr
->data
;
278 return fme_mgr_get_retimer_status(fme
, status
);
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
,
294 static int ifpga_adapter_enumerate(struct opae_adapter
*adapter
)
296 struct ifpga_hw
*hw
= malloc(sizeof(*hw
));
299 opae_memset(hw
, 0, sizeof(*hw
));
300 hw
->pci_data
= adapter
->data
;
301 hw
->adapter
= adapter
;
302 if (ifpga_bus_enumerate(hw
))
304 return ifpga_bus_init(hw
);
311 struct opae_adapter_ops ifpga_adapter_ops
= {
312 .enumerate
= ifpga_adapter_enumerate
,
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.
324 * - 0: Success, partial reconfiguration finished.
325 * - <0: Error code returned in partial reconfiguration.
327 int ifpga_pr(struct ifpga_hw
*hw
, u32 port_id
, void *buffer
, u32 size
,
330 if (!is_valid_port_id(hw
, port_id
))
333 return do_pr(hw
, port_id
, buffer
, size
, status
);
336 int ifpga_get_prop(struct ifpga_hw
*hw
, u32 fiu_id
, u32 port_id
,
337 struct feature_prop
*prop
)
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
))
348 return port_get_prop(&hw
->port
[port_id
], prop
);
354 int ifpga_set_prop(struct ifpga_hw
*hw
, u32 fiu_id
, u32 port_id
,
355 struct feature_prop
*prop
)
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
))
366 return port_set_prop(&hw
->port
[port_id
], prop
);
372 int ifpga_set_irq(struct ifpga_hw
*hw
, u32 fiu_id
, u32 port_id
,
373 u32 feature_id
, void *irq_set
)
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
))
384 return port_set_irq(&hw
->port
[port_id
], feature_id
, irq_set
);