Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright 2019-2024 Advanced Micro Devices, Inc. 3 : : */ 4 : : 5 : : #include <stdint.h> 6 : : #include <stdlib.h> 7 : : #include <errno.h> 8 : : 9 : : #include <rte_errno.h> 10 : : #include <rte_common.h> 11 : : #include <rte_log.h> 12 : : #include <rte_eal.h> 13 : : #include <bus_vdev_driver.h> 14 : : #include <rte_dev.h> 15 : : #include <rte_string_fns.h> 16 : : #include <rte_kvargs.h> 17 : : 18 : : #include "ionic.h" 19 : : #include "ionic_common.h" 20 : : #include "ionic_logs.h" 21 : : #include "ionic_ethdev.h" 22 : : 23 : : #define IONIC_VDEV_DEV_BAR 0 24 : : #define IONIC_VDEV_INTR_CTL_BAR 1 25 : : #define IONIC_VDEV_INTR_CFG_BAR 2 26 : : #define IONIC_VDEV_DB_BAR 3 27 : : #define IONIC_VDEV_BARS_MAX 4 28 : : 29 : : #define IONIC_VDEV_DEV_INFO_REGS_OFFSET 0x0000 30 : : #define IONIC_VDEV_DEV_CMD_REGS_OFFSET 0x0800 31 : : 32 : : #define IONIC_VDEV_FW_WAIT_US 1000 /* 1ms */ 33 : : #define IONIC_VDEV_FW_WAIT_MAX 5000 /* 5s */ 34 : : 35 : : static int 36 : 0 : ionic_vdev_setup(struct ionic_adapter *adapter) 37 : : { 38 : : struct ionic_bars *bars = &adapter->bars; 39 : : struct ionic_dev *idev = &adapter->idev; 40 : : uint8_t *bar0_base; 41 : : uint32_t sig; 42 : : uint32_t fw_waits = 0; 43 : : uint8_t fw; 44 : : 45 : 0 : IONIC_PRINT_CALL(); 46 : : 47 : : /* BAR0: dev_cmd and interrupts */ 48 [ # # ]: 0 : if (bars->num_bars < 1) { 49 : 0 : IONIC_PRINT(ERR, "No bars found, aborting"); 50 : 0 : return -EFAULT; 51 : : } 52 : : 53 : 0 : bar0_base = bars->bar[IONIC_VDEV_DEV_BAR].vaddr; 54 : 0 : idev->dev_info = (union ionic_dev_info_regs *) 55 : : &bar0_base[IONIC_VDEV_DEV_INFO_REGS_OFFSET]; 56 : 0 : idev->dev_cmd = (union ionic_dev_cmd_regs *) 57 : 0 : &bar0_base[IONIC_VDEV_DEV_CMD_REGS_OFFSET]; 58 : 0 : idev->intr_ctrl = (void *)bars->bar[IONIC_VDEV_INTR_CTL_BAR].vaddr; 59 : 0 : idev->db_pages = (void *)bars->bar[IONIC_VDEV_DB_BAR].vaddr; 60 : : 61 : : sig = ioread32(&idev->dev_info->signature); 62 [ # # ]: 0 : if (sig != IONIC_DEV_INFO_SIGNATURE) { 63 : 0 : IONIC_PRINT(ERR, "Incompatible firmware signature %x", sig); 64 : 0 : return -EFAULT; 65 : : } 66 : : 67 : : /* Wait for the FW to indicate readiness */ 68 : : while (1) { 69 : 0 : fw = ioread8(&idev->dev_info->fw_status); 70 [ # # ]: 0 : if ((fw & IONIC_FW_STS_F_RUNNING) != 0) 71 : : break; 72 : : 73 [ # # ]: 0 : if (fw_waits > IONIC_VDEV_FW_WAIT_MAX) { 74 : 0 : IONIC_PRINT(ERR, "Firmware readiness bit not set"); 75 : 0 : return -ETIMEDOUT; 76 : : } 77 : : 78 : 0 : fw_waits++; 79 : 0 : rte_delay_us_block(IONIC_VDEV_FW_WAIT_US); 80 : : } 81 : 0 : IONIC_PRINT(DEBUG, "Firmware ready (%u waits)", fw_waits); 82 : : 83 [ # # ]: 0 : adapter->name = rte_vdev_device_name(adapter->bus_dev); 84 : : 85 : 0 : return 0; 86 : : } 87 : : 88 : : static void 89 : 0 : ionic_vdev_poll(struct ionic_adapter *adapter) 90 : : { 91 : 0 : ionic_dev_interrupt_handler(adapter); 92 : 0 : } 93 : : 94 : : static void 95 : 0 : ionic_vdev_unmap_bars(struct ionic_adapter *adapter) 96 : : { 97 : : struct ionic_bars *bars = &adapter->bars; 98 : : uint32_t i; 99 : : 100 [ # # ]: 0 : for (i = 0; i < IONIC_VDEV_BARS_MAX; i++) 101 : 0 : ionic_uio_rel_rsrc(adapter->name, i, &bars->bar[i]); 102 : 0 : } 103 : : 104 : : static const struct ionic_dev_intf ionic_vdev_intf = { 105 : : .setup = ionic_vdev_setup, 106 : : .poll = ionic_vdev_poll, 107 : : .unmap_bars = ionic_vdev_unmap_bars, 108 : : }; 109 : : 110 : : static int 111 : 0 : eth_ionic_vdev_probe(struct rte_vdev_device *vdev) 112 : : { 113 [ # # ]: 0 : struct ionic_bars bars = {}; 114 : : const char *name = rte_vdev_device_name(vdev); 115 : : unsigned int i; 116 : : 117 [ # # ]: 0 : IONIC_PRINT(NOTICE, "Initializing device %s", 118 : : rte_eal_process_type() == RTE_PROC_SECONDARY ? 119 : : "[SECONDARY]" : ""); 120 : : 121 : 0 : ionic_uio_scan_mnet_devices(); 122 : : 123 [ # # ]: 0 : for (i = 0; i < IONIC_VDEV_BARS_MAX; i++) 124 : 0 : ionic_uio_get_rsrc(name, i, &bars.bar[i]); 125 : : 126 : 0 : bars.num_bars = IONIC_VDEV_BARS_MAX; 127 : : 128 : 0 : return eth_ionic_dev_probe((void *)vdev, 129 : : &vdev->device, 130 : : &bars, 131 : : &ionic_vdev_intf, 132 : : IONIC_DEV_ID_ETH_VF, 133 : : IONIC_PENSANDO_VENDOR_ID); 134 : : } 135 : : 136 : : static int 137 : 0 : eth_ionic_vdev_remove(struct rte_vdev_device *vdev) 138 : : { 139 : 0 : return eth_ionic_dev_remove(&vdev->device); 140 : : } 141 : : 142 : : static struct rte_vdev_driver rte_vdev_ionic_pmd = { 143 : : .probe = eth_ionic_vdev_probe, 144 : : .remove = eth_ionic_vdev_remove, 145 : : }; 146 : : 147 : 252 : RTE_PMD_REGISTER_VDEV(net_ionic, rte_vdev_ionic_pmd);