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 uint32_t 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 (class_str == NULL) 27 return *dev_class; 28 29 if (strcmp(class_str, "vdpa") == 0) { 30 *dev_class = SFC_EFX_DEV_CLASS_VDPA; 31 } else if (strcmp(class_str, "net") == 0) { 32 *dev_class = SFC_EFX_DEV_CLASS_NET; 33 } else { 34 SFC_EFX_LOG(ERR, "Unsupported class %s.", class_str); 35 *dev_class = SFC_EFX_DEV_CLASS_INVALID; 36 } 37 38 return 0; 39 } 40 41 enum sfc_efx_dev_class 42 sfc_efx_dev_class_get(struct rte_devargs *devargs) 43 { 44 struct rte_kvargs *kvargs; 45 const char *key = SFC_EFX_KVARG_DEV_CLASS; 46 enum sfc_efx_dev_class dev_class = SFC_EFX_DEV_CLASS_NET; 47 48 if (devargs == NULL) 49 return dev_class; 50 51 kvargs = rte_kvargs_parse(devargs->args, NULL); 52 if (kvargs == NULL) 53 return dev_class; 54 55 if (rte_kvargs_count(kvargs, key) != 0) { 56 rte_kvargs_process(kvargs, key, sfc_efx_kvarg_dev_class_handler, 57 &dev_class); 58 } 59 60 rte_kvargs_free(kvargs); 61 62 return dev_class; 63 } 64 65 static efx_rc_t 66 sfc_efx_find_mem_bar(efsys_pci_config_t *configp, int bar_index, 67 efsys_bar_t *barp) 68 { 69 efsys_bar_t result; 70 struct rte_pci_device *dev; 71 72 memset(&result, 0, sizeof(result)); 73 74 if (bar_index < 0 || bar_index >= PCI_MAX_RESOURCE) 75 return -EINVAL; 76 77 dev = configp->espc_dev; 78 79 result.esb_rid = bar_index; 80 result.esb_dev = dev; 81 result.esb_base = dev->mem_resource[bar_index].addr; 82 83 *barp = result; 84 85 return 0; 86 } 87 88 static efx_rc_t 89 sfc_efx_pci_config_readd(efsys_pci_config_t *configp, uint32_t offset, 90 efx_dword_t *edp) 91 { 92 int rc; 93 94 rc = rte_pci_read_config(configp->espc_dev, edp->ed_u32, sizeof(*edp), 95 offset); 96 97 return (rc < 0 || rc != sizeof(*edp)) ? EIO : 0; 98 } 99 100 int 101 sfc_efx_family(struct rte_pci_device *pci_dev, 102 efx_bar_region_t *mem_ebrp, efx_family_t *family) 103 { 104 static const efx_pci_ops_t ops = { 105 .epo_config_readd = sfc_efx_pci_config_readd, 106 .epo_find_mem_bar = sfc_efx_find_mem_bar, 107 }; 108 109 efsys_pci_config_t espcp; 110 int rc; 111 112 espcp.espc_dev = pci_dev; 113 114 rc = efx_family_probe_bar(pci_dev->id.vendor_id, 115 pci_dev->id.device_id, 116 &espcp, &ops, family, mem_ebrp); 117 118 return rc; 119 } 120 121 RTE_INIT(sfc_efx_register_logtype) 122 { 123 int ret; 124 125 ret = rte_log_register_type_and_pick_level("pmd.common.sfc_efx", 126 RTE_LOG_NOTICE); 127 sfc_efx_logtype = (ret < 0) ? RTE_LOGTYPE_PMD : ret; 128 } 129