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 } 457