X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fsfc_efx%2Fsfc_efx.c;h=0b78933d9f600d0318435d21a224045c3244e161;hb=8076e40cde3b5230ac488aa44baa4dcf73993aca;hp=d7a84c9835a40219bba447a7ac42e378c36ce51b;hpb=672386c1e9e1f64f7aa3b1360ad22dc737ea8d72;p=dpdk.git diff --git a/drivers/common/sfc_efx/sfc_efx.c b/drivers/common/sfc_efx/sfc_efx.c index d7a84c9835..0b78933d9f 100644 --- a/drivers/common/sfc_efx/sfc_efx.c +++ b/drivers/common/sfc_efx/sfc_efx.c @@ -7,12 +7,117 @@ * for Solarflare) and Solarflare Communications, Inc. */ +#include #include +#include +#include #include "sfc_efx_log.h" +#include "sfc_efx.h" uint32_t sfc_efx_logtype; +static int +sfc_efx_kvarg_dev_class_handler(__rte_unused const char *key, + const char *class_str, void *opaque) +{ + enum sfc_efx_dev_class *dev_class = opaque; + + if (class_str == NULL) + return *dev_class; + + if (strcmp(class_str, "vdpa") == 0) { + *dev_class = SFC_EFX_DEV_CLASS_VDPA; + } else if (strcmp(class_str, "net") == 0) { + *dev_class = SFC_EFX_DEV_CLASS_NET; + } else { + SFC_EFX_LOG(ERR, "Unsupported class %s.", class_str); + *dev_class = SFC_EFX_DEV_CLASS_INVALID; + } + + return 0; +} + +enum sfc_efx_dev_class +sfc_efx_dev_class_get(struct rte_devargs *devargs) +{ + struct rte_kvargs *kvargs; + const char *key = SFC_EFX_KVARG_DEV_CLASS; + enum sfc_efx_dev_class dev_class = SFC_EFX_DEV_CLASS_NET; + + if (devargs == NULL) + return dev_class; + + kvargs = rte_kvargs_parse(devargs->args, NULL); + if (kvargs == NULL) + return dev_class; + + if (rte_kvargs_count(kvargs, key) != 0) { + rte_kvargs_process(kvargs, key, sfc_efx_kvarg_dev_class_handler, + &dev_class); + } + + rte_kvargs_free(kvargs); + + return dev_class; +} + +static efx_rc_t +sfc_efx_find_mem_bar(efsys_pci_config_t *configp, int bar_index, + efsys_bar_t *barp) +{ + efsys_bar_t result; + struct rte_pci_device *dev; + + memset(&result, 0, sizeof(result)); + + if (bar_index < 0 || bar_index >= PCI_MAX_RESOURCE) + return -EINVAL; + + dev = configp->espc_dev; + + result.esb_rid = bar_index; + result.esb_dev = dev; + result.esb_base = dev->mem_resource[bar_index].addr; + + *barp = result; + + return 0; +} + +static efx_rc_t +sfc_efx_pci_config_readd(efsys_pci_config_t *configp, uint32_t offset, + efx_dword_t *edp) +{ + int rc; + + rc = rte_pci_read_config(configp->espc_dev, edp->ed_u32, sizeof(*edp), + offset); + + return (rc < 0 || rc != sizeof(*edp)) ? EIO : 0; +} + +int +sfc_efx_family(struct rte_pci_device *pci_dev, + efx_bar_region_t *mem_ebrp, efx_family_t *family) +{ + static const efx_pci_ops_t ops = { + .epo_config_readd = sfc_efx_pci_config_readd, + .epo_find_mem_bar = sfc_efx_find_mem_bar, + }; + + efsys_pci_config_t espcp; + int rc; + + espcp.espc_dev = pci_dev; + + rc = efx_family_probe_bar(pci_dev->id.vendor_id, + pci_dev->id.device_id, + &espcp, &ops, family, mem_ebrp); + + return rc; +} + RTE_INIT(sfc_efx_register_logtype) { int ret;