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 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 IONIC_PRINT_CALL(); 46 47 /* BAR0: dev_cmd and interrupts */ 48 if (bars->num_bars < 1) { 49 IONIC_PRINT(ERR, "No bars found, aborting"); 50 return -EFAULT; 51 } 52 53 bar0_base = bars->bar[IONIC_VDEV_DEV_BAR].vaddr; 54 idev->dev_info = (union ionic_dev_info_regs *) 55 &bar0_base[IONIC_VDEV_DEV_INFO_REGS_OFFSET]; 56 idev->dev_cmd = (union ionic_dev_cmd_regs *) 57 &bar0_base[IONIC_VDEV_DEV_CMD_REGS_OFFSET]; 58 idev->intr_ctrl = (void *)bars->bar[IONIC_VDEV_INTR_CTL_BAR].vaddr; 59 idev->db_pages = (void *)bars->bar[IONIC_VDEV_DB_BAR].vaddr; 60 61 sig = ioread32(&idev->dev_info->signature); 62 if (sig != IONIC_DEV_INFO_SIGNATURE) { 63 IONIC_PRINT(ERR, "Incompatible firmware signature %x", sig); 64 return -EFAULT; 65 } 66 67 /* Wait for the FW to indicate readiness */ 68 while (1) { 69 fw = ioread8(&idev->dev_info->fw_status); 70 if ((fw & IONIC_FW_STS_F_RUNNING) != 0) 71 break; 72 73 if (fw_waits > IONIC_VDEV_FW_WAIT_MAX) { 74 IONIC_PRINT(ERR, "Firmware readiness bit not set"); 75 return -ETIMEDOUT; 76 } 77 78 fw_waits++; 79 rte_delay_us_block(IONIC_VDEV_FW_WAIT_US); 80 } 81 IONIC_PRINT(DEBUG, "Firmware ready (%u waits)", fw_waits); 82 83 adapter->name = rte_vdev_device_name(adapter->bus_dev); 84 85 return 0; 86 } 87 88 static void 89 ionic_vdev_poll(struct ionic_adapter *adapter) 90 { 91 ionic_dev_interrupt_handler(adapter); 92 } 93 94 static void 95 ionic_vdev_unmap_bars(struct ionic_adapter *adapter) 96 { 97 struct ionic_bars *bars = &adapter->bars; 98 uint32_t i; 99 100 for (i = 0; i < IONIC_VDEV_BARS_MAX; i++) 101 ionic_uio_rel_rsrc(adapter->name, i, &bars->bar[i]); 102 } 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 eth_ionic_vdev_probe(struct rte_vdev_device *vdev) 112 { 113 struct ionic_bars bars = {}; 114 const char *name = rte_vdev_device_name(vdev); 115 unsigned int i; 116 117 IONIC_PRINT(NOTICE, "Initializing device %s", 118 rte_eal_process_type() == RTE_PROC_SECONDARY ? 119 "[SECONDARY]" : ""); 120 121 ionic_uio_scan_mnet_devices(); 122 123 for (i = 0; i < IONIC_VDEV_BARS_MAX; i++) 124 ionic_uio_get_rsrc(name, i, &bars.bar[i]); 125 126 bars.num_bars = IONIC_VDEV_BARS_MAX; 127 128 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 eth_ionic_vdev_remove(struct rte_vdev_device *vdev) 138 { 139 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 RTE_PMD_REGISTER_VDEV(net_ionic, rte_vdev_ionic_pmd); 148