Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright 2021-2024 Advanced Micro Devices, Inc. 3 : : */ 4 : : 5 : : #include <stdint.h> 6 : : #include <errno.h> 7 : : 8 : : #include <rte_errno.h> 9 : : #include <rte_common.h> 10 : : #include <rte_log.h> 11 : : #include <rte_eal.h> 12 : : #include <bus_vdev_driver.h> 13 : : #include <rte_dev.h> 14 : : #include <rte_string_fns.h> 15 : : 16 : : #include "ionic_crypto.h" 17 : : 18 : : #define IOCPT_VDEV_DEV_BAR 0 19 : : #define IOCPT_VDEV_INTR_CTL_BAR 1 20 : : #define IOCPT_VDEV_INTR_CFG_BAR 2 21 : : #define IOCPT_VDEV_DB_BAR 3 22 : : #define IOCPT_VDEV_BARS_MAX 4 23 : : 24 : : #define IOCPT_VDEV_DEV_INFO_REGS_OFFSET 0x0000 25 : : #define IOCPT_VDEV_DEV_CMD_REGS_OFFSET 0x0800 26 : : 27 : : #define IOCPT_VDEV_FW_WAIT_US 1000 /* 1ms */ 28 : : #define IOCPT_VDEV_FW_WAIT_MAX 5000 /* 5s */ 29 : : 30 : : static int 31 : 0 : iocpt_vdev_setup_bars(struct iocpt_dev *dev) 32 : : { 33 : : struct iocpt_dev_bars *bars = &dev->bars; 34 : : uint8_t *bar0_base; 35 : : uint32_t fw_waits = 0; 36 : : uint8_t fw; 37 : : 38 : 0 : IOCPT_PRINT_CALL(); 39 : : 40 : : /* BAR0: dev_cmd */ 41 : 0 : bar0_base = bars->bar[IOCPT_VDEV_DEV_BAR].vaddr; 42 : 0 : dev->dev_info = (union iocpt_dev_info_regs *) 43 : : &bar0_base[IOCPT_VDEV_DEV_INFO_REGS_OFFSET]; 44 : 0 : dev->dev_cmd = (union iocpt_dev_cmd_regs *) 45 : 0 : &bar0_base[IOCPT_VDEV_DEV_CMD_REGS_OFFSET]; 46 : : 47 : : /* BAR1: interrupts */ 48 : 0 : dev->intr_ctrl = (void *)bars->bar[IOCPT_VDEV_INTR_CTL_BAR].vaddr; 49 : : 50 : : /* BAR3: doorbells */ 51 : 0 : dev->db_pages = (void *)bars->bar[IOCPT_VDEV_DB_BAR].vaddr; 52 : : 53 : : /* Wait for the FW to indicate readiness */ 54 : : while (1) { 55 : 0 : fw = ioread8(&dev->dev_info->fw_status); 56 [ # # ]: 0 : if ((fw & IOCPT_FW_STS_F_RUNNING) != 0) 57 : : break; 58 : : 59 [ # # ]: 0 : if (fw_waits > IOCPT_VDEV_FW_WAIT_MAX) { 60 : 0 : IOCPT_PRINT(ERR, "Firmware readiness bit not set"); 61 : 0 : return -ETIMEDOUT; 62 : : } 63 : : 64 : 0 : fw_waits++; 65 : 0 : rte_delay_us_block(IOCPT_VDEV_FW_WAIT_US); 66 : : } 67 : 0 : IOCPT_PRINT(DEBUG, "Firmware ready (%u waits)", fw_waits); 68 : : 69 [ # # ]: 0 : dev->name = rte_vdev_device_name(dev->bus_dev); 70 : : 71 : 0 : return 0; 72 : : } 73 : : 74 : : static void 75 : 0 : iocpt_vdev_unmap_bars(struct iocpt_dev *dev) 76 : : { 77 : : struct iocpt_dev_bars *bars = &dev->bars; 78 : : uint32_t i; 79 : : 80 [ # # ]: 0 : for (i = 0; i < IOCPT_VDEV_BARS_MAX; i++) 81 : 0 : ionic_uio_rel_rsrc(dev->name, i, &bars->bar[i]); 82 : 0 : } 83 : : 84 : : static uint8_t iocpt_vdev_driver_id; 85 : : static const struct iocpt_dev_intf iocpt_vdev_intf = { 86 : : .setup_bars = iocpt_vdev_setup_bars, 87 : : .unmap_bars = iocpt_vdev_unmap_bars, 88 : : }; 89 : : 90 : : static int 91 : 0 : iocpt_vdev_probe(struct rte_vdev_device *vdev) 92 : : { 93 [ # # ]: 0 : struct iocpt_dev_bars bars = {}; 94 : : const char *name = rte_vdev_device_name(vdev); 95 : : unsigned int i; 96 : : 97 [ # # ]: 0 : IOCPT_PRINT(NOTICE, "Initializing device %s%s", name, 98 : : rte_eal_process_type() == RTE_PROC_SECONDARY ? 99 : : " [SECONDARY]" : ""); 100 : : 101 : 0 : ionic_uio_scan_mcrypt_devices(); 102 : : 103 [ # # ]: 0 : for (i = 0; i < IOCPT_VDEV_BARS_MAX; i++) 104 : 0 : ionic_uio_get_rsrc(name, i, &bars.bar[i]); 105 : : 106 : 0 : bars.num_bars = IOCPT_VDEV_BARS_MAX; 107 : : 108 : 0 : return iocpt_probe((void *)vdev, &vdev->device, 109 : : &bars, &iocpt_vdev_intf, 110 : 0 : iocpt_vdev_driver_id, rte_socket_id()); 111 : : } 112 : : 113 : : static int 114 : 0 : iocpt_vdev_remove(struct rte_vdev_device *vdev) 115 : : { 116 : 0 : return iocpt_remove(&vdev->device); 117 : : } 118 : : 119 : : static struct rte_vdev_driver rte_vdev_iocpt_pmd = { 120 : : .probe = iocpt_vdev_probe, 121 : : .remove = iocpt_vdev_remove, 122 : : }; 123 : : 124 : : static struct cryptodev_driver rte_vdev_iocpt_drv; 125 : : 126 : 252 : RTE_PMD_REGISTER_VDEV(crypto_ionic, rte_vdev_iocpt_pmd); 127 : 252 : RTE_PMD_REGISTER_CRYPTO_DRIVER(rte_vdev_iocpt_drv, rte_vdev_iocpt_pmd.driver, 128 : : iocpt_vdev_driver_id);