1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2018-2022 Advanced Micro Devices, Inc. 3 */ 4 5 #include <stdio.h> 6 #include <errno.h> 7 #include <string.h> 8 #include <stdint.h> 9 10 #include <rte_common.h> 11 #include <rte_interrupts.h> 12 #include <rte_log.h> 13 #include <rte_pci.h> 14 #include <bus_pci_driver.h> 15 #include <rte_eal.h> 16 #include <ethdev_pci.h> 17 #include <rte_dev.h> 18 #include <rte_kvargs.h> 19 20 #include "ionic.h" 21 #include "ionic_if.h" 22 #include "ionic_dev.h" 23 #include "ionic_ethdev.h" 24 #include "ionic_logs.h" 25 26 static const struct rte_pci_id pci_id_ionic_map[] = { 27 { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_PF) }, 28 { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_VF) }, 29 { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_MGMT) }, 30 { .vendor_id = 0, /* sentinel */ }, 31 }; 32 33 static int 34 ionic_pci_setup(struct ionic_adapter *adapter) 35 { 36 struct ionic_dev_bar *bar = adapter->bars.bar; 37 unsigned int num_bars = adapter->bars.num_bars; 38 struct ionic_dev *idev = &adapter->idev; 39 struct rte_pci_device *bus_dev = adapter->bus_dev; 40 uint32_t sig; 41 uint8_t *bar0_base; 42 unsigned int i; 43 44 /* BAR0: dev_cmd and interrupts */ 45 if (num_bars < 1) { 46 IONIC_PRINT(ERR, "No bars found, aborting"); 47 return -EFAULT; 48 } 49 50 if (bar->len < IONIC_BAR0_SIZE) { 51 IONIC_PRINT(ERR, "Resource bar size %lu too small, aborting", 52 bar->len); 53 return -EFAULT; 54 } 55 56 bar0_base = bar->vaddr; 57 idev->dev_info = (union ionic_dev_info_regs *) 58 &bar0_base[IONIC_BAR0_DEV_INFO_REGS_OFFSET]; 59 idev->dev_cmd = (union ionic_dev_cmd_regs *) 60 &bar0_base[IONIC_BAR0_DEV_CMD_REGS_OFFSET]; 61 idev->intr_status = (struct ionic_intr_status *) 62 &bar0_base[IONIC_BAR0_INTR_STATUS_OFFSET]; 63 idev->intr_ctrl = (struct ionic_intr *) 64 &bar0_base[IONIC_BAR0_INTR_CTRL_OFFSET]; 65 66 sig = ioread32(&idev->dev_info->signature); 67 if (sig != IONIC_DEV_INFO_SIGNATURE) { 68 IONIC_PRINT(ERR, "Incompatible firmware signature %#x", 69 sig); 70 return -EFAULT; 71 } 72 73 for (i = 0; i < IONIC_DEVINFO_FWVERS_BUFLEN; i++) 74 adapter->fw_version[i] = 75 ioread8(&idev->dev_info->fw_version[i]); 76 adapter->fw_version[IONIC_DEVINFO_FWVERS_BUFLEN - 1] = '\0'; 77 78 adapter->name = bus_dev->device.name; 79 80 IONIC_PRINT(DEBUG, "%s firmware version: %s", 81 adapter->name, adapter->fw_version); 82 83 /* BAR1: doorbells */ 84 bar++; 85 if (num_bars < IONIC_BARS_MIN) { 86 IONIC_PRINT(ERR, "Doorbell bar missing, aborting"); 87 return -EFAULT; 88 } 89 90 idev->db_pages = bar->vaddr; 91 92 return 0; 93 } 94 95 const char *ionic_pci_devargs_arr[] = { 96 PMD_IONIC_CMB_KVARG, 97 NULL, 98 }; 99 100 static int 101 ionic_pci_devarg_cmb(const char *key __rte_unused, const char *val, void *arg) 102 { 103 struct ionic_adapter *adapter = arg; 104 105 if (!strcmp(val, "1")) { 106 IONIC_PRINT(NOTICE, "%s enabled", PMD_IONIC_CMB_KVARG); 107 adapter->q_in_cmb = true; 108 } else if (!strcmp(val, "0")) { 109 IONIC_PRINT(DEBUG, "%s disabled (default)", 110 PMD_IONIC_CMB_KVARG); 111 } else { 112 IONIC_PRINT(ERR, "%s=%s invalid, use 1 or 0", 113 PMD_IONIC_CMB_KVARG, val); 114 return -ERANGE; 115 } 116 117 return 0; 118 } 119 120 static int 121 ionic_pci_devargs(struct ionic_adapter *adapter, struct rte_devargs *devargs) 122 { 123 struct rte_kvargs *kvlist; 124 int err = 0; 125 126 if (!devargs) 127 return 0; 128 129 kvlist = rte_kvargs_parse(devargs->args, ionic_pci_devargs_arr); 130 if (!kvlist) { 131 IONIC_PRINT(ERR, "Couldn't parse args '%s'", devargs->args); 132 return -EINVAL; 133 } 134 135 if (rte_kvargs_count(kvlist, PMD_IONIC_CMB_KVARG) == 1) { 136 err = rte_kvargs_process(kvlist, PMD_IONIC_CMB_KVARG, 137 ionic_pci_devarg_cmb, adapter); 138 if (err < 0) 139 goto free_kvlist; 140 } 141 142 free_kvlist: 143 rte_kvargs_free(kvlist); 144 return err; 145 } 146 147 static void 148 ionic_pci_copy_bus_info(struct ionic_adapter *adapter, 149 struct rte_eth_dev *eth_dev) 150 { 151 rte_eth_copy_pci_info(eth_dev, adapter->bus_dev); 152 } 153 154 static int 155 ionic_pci_configure_intr(struct ionic_adapter *adapter) 156 { 157 struct rte_pci_device *pci_dev = 158 (struct rte_pci_device *)(adapter->bus_dev); 159 struct rte_intr_handle *intr_handle = pci_dev->intr_handle; 160 int err; 161 162 IONIC_PRINT(ERR, "Configuring %u intrs", adapter->nintrs); 163 164 if (rte_intr_efd_enable(intr_handle, adapter->nintrs)) { 165 IONIC_PRINT(ERR, "Fail to create eventfd"); 166 return -1; 167 } 168 169 if (rte_intr_dp_is_en(intr_handle)) { 170 IONIC_PRINT(NOTICE, 171 "Packet I/O interrupt on datapath is enabled"); 172 if (rte_intr_vec_list_alloc(intr_handle, "intr_vec", 173 adapter->nintrs)) { 174 IONIC_PRINT(ERR, "Failed to allocate %u vectors", 175 adapter->nintrs); 176 return -ENOMEM; 177 } 178 } 179 180 err = rte_intr_callback_register(intr_handle, 181 ionic_dev_interrupt_handler, 182 adapter); 183 if (err) { 184 IONIC_PRINT(ERR, 185 "Failure registering interrupts handler (%d)", err); 186 return err; 187 } 188 189 /* enable intr mapping */ 190 err = rte_intr_enable(intr_handle); 191 if (err) { 192 IONIC_PRINT(ERR, "Failure enabling interrupts (%d)", err); 193 return err; 194 } 195 196 return 0; 197 } 198 199 static void 200 ionic_pci_unconfigure_intr(struct ionic_adapter *adapter) 201 { 202 struct rte_pci_device *pci_dev = 203 (struct rte_pci_device *)(adapter->bus_dev); 204 struct rte_intr_handle *intr_handle = pci_dev->intr_handle; 205 206 rte_intr_disable(intr_handle); 207 208 rte_intr_callback_unregister(intr_handle, 209 ionic_dev_interrupt_handler, 210 adapter); 211 } 212 213 static const struct ionic_dev_intf ionic_pci_intf = { 214 .setup = ionic_pci_setup, 215 .devargs = ionic_pci_devargs, 216 .copy_bus_info = ionic_pci_copy_bus_info, 217 .configure_intr = ionic_pci_configure_intr, 218 .unconfigure_intr = ionic_pci_unconfigure_intr, 219 }; 220 221 static int 222 eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 223 struct rte_pci_device *pci_dev) 224 { 225 struct rte_mem_resource *resource; 226 struct ionic_bars bars; 227 unsigned long i; 228 229 IONIC_PRINT(NOTICE, "Initializing device %s %s", 230 pci_dev->device.name, 231 rte_eal_process_type() == RTE_PROC_SECONDARY ? 232 "[SECONDARY]" : ""); 233 234 bars.num_bars = 0; 235 for (i = 0; i < PCI_MAX_RESOURCE && i < IONIC_BARS_MAX; i++) { 236 resource = &pci_dev->mem_resource[i]; 237 if (resource->phys_addr == 0 || resource->len == 0) 238 continue; 239 240 bars.bar[bars.num_bars].vaddr = resource->addr; 241 bars.bar[bars.num_bars].bus_addr = resource->phys_addr; 242 bars.bar[bars.num_bars].len = resource->len; 243 bars.num_bars++; 244 } 245 246 return eth_ionic_dev_probe((void *)pci_dev, 247 &pci_dev->device, 248 &bars, 249 &ionic_pci_intf, 250 pci_dev->id.device_id, 251 pci_dev->id.vendor_id); 252 } 253 254 static int 255 eth_ionic_pci_remove(struct rte_pci_device *pci_dev) 256 { 257 return eth_ionic_dev_remove(&pci_dev->device); 258 } 259 260 static struct rte_pci_driver rte_pci_ionic_pmd = { 261 .id_table = pci_id_ionic_map, 262 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC | 263 RTE_PCI_DRV_WC_ACTIVATE, 264 .probe = eth_ionic_pci_probe, 265 .remove = eth_ionic_pci_remove, 266 }; 267 268 RTE_PMD_REGISTER_PCI(net_ionic_pci, rte_pci_ionic_pmd); 269 RTE_PMD_REGISTER_PCI_TABLE(net_ionic_pci, pci_id_ionic_map); 270 RTE_PMD_REGISTER_KMOD_DEP(net_ionic_pci, "* igb_uio | uio_pci_generic | vfio-pci"); 271 RTE_PMD_REGISTER_PARAM_STRING(net_ionic_pci, 272 PMD_IONIC_CMB_KVARG "=<0|1>" 273 ); 274