1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2019 Solarflare Communications Inc. 5 * 6 * This software was jointly developed between OKTET Labs (under contract 7 * for Solarflare) and Solarflare Communications, Inc. 8 */ 9 10 #include <string.h> 11 #include <rte_log.h> 12 #include <rte_kvargs.h> 13 #include <rte_devargs.h> 14 15 #include "sfc_efx_log.h" 16 #include "sfc_efx.h" 17 18 int sfc_efx_logtype; 19 20 static int 21 sfc_efx_kvarg_dev_class_handler(__rte_unused const char *key, 22 const char *class_str, void *opaque) 23 { 24 enum sfc_efx_dev_class *dev_class = opaque; 25 26 if (strcmp(class_str, "vdpa") == 0) { 27 *dev_class = SFC_EFX_DEV_CLASS_VDPA; 28 } else if (strcmp(class_str, "net") == 0) { 29 *dev_class = SFC_EFX_DEV_CLASS_NET; 30 } else { 31 SFC_EFX_LOG(ERR, "Unsupported class %s.", class_str); 32 *dev_class = SFC_EFX_DEV_CLASS_INVALID; 33 } 34 35 return 0; 36 } 37 38 enum sfc_efx_dev_class 39 sfc_efx_dev_class_get(struct rte_devargs *devargs) 40 { 41 struct rte_kvargs *kvargs; 42 enum sfc_efx_dev_class dev_class = SFC_EFX_DEV_CLASS_NET; 43 44 if (devargs == NULL) 45 return dev_class; 46 47 kvargs = rte_kvargs_parse(devargs->args, NULL); 48 if (kvargs == NULL) 49 return dev_class; 50 51 if (rte_kvargs_count(kvargs, RTE_DEVARGS_KEY_CLASS) != 0) { 52 rte_kvargs_process(kvargs, RTE_DEVARGS_KEY_CLASS, 53 sfc_efx_kvarg_dev_class_handler, &dev_class); 54 } 55 56 rte_kvargs_free(kvargs); 57 58 return dev_class; 59 } 60 61 static efx_rc_t 62 sfc_efx_find_mem_bar(efsys_pci_config_t *configp, int bar_index, 63 efsys_bar_t *barp) 64 { 65 efsys_bar_t result; 66 struct rte_pci_device *dev; 67 68 memset(&result, 0, sizeof(result)); 69 70 if (bar_index < 0 || bar_index >= PCI_MAX_RESOURCE) 71 return -EINVAL; 72 73 dev = configp->espc_dev; 74 75 result.esb_rid = bar_index; 76 result.esb_dev = dev; 77 result.esb_base = dev->mem_resource[bar_index].addr; 78 79 *barp = result; 80 81 return 0; 82 } 83 84 static efx_rc_t 85 sfc_efx_pci_config_readd(efsys_pci_config_t *configp, uint32_t offset, 86 efx_dword_t *edp) 87 { 88 int rc; 89 90 rc = rte_pci_read_config(configp->espc_dev, edp->ed_u32, sizeof(*edp), 91 offset); 92 93 return (rc < 0 || rc != sizeof(*edp)) ? EIO : 0; 94 } 95 96 int 97 sfc_efx_family(struct rte_pci_device *pci_dev, 98 efx_bar_region_t *mem_ebrp, efx_family_t *family) 99 { 100 static const efx_pci_ops_t ops = { 101 .epo_config_readd = sfc_efx_pci_config_readd, 102 .epo_find_mem_bar = sfc_efx_find_mem_bar, 103 }; 104 105 efsys_pci_config_t espcp; 106 int rc; 107 108 espcp.espc_dev = pci_dev; 109 110 rc = efx_family_probe_bar(pci_dev->id.vendor_id, 111 pci_dev->id.device_id, 112 &espcp, &ops, family, mem_ebrp); 113 114 return rc; 115 } 116 117 RTE_LOG_REGISTER_DEFAULT(sfc_efx_logtype, NOTICE); 118