common/sfc_efx/base: fix indication of MAE encap support
[dpdk.git] / drivers / common / sfc_efx / sfc_efx.c
index d7a84c9..0b78933 100644 (file)
  * for Solarflare) and Solarflare Communications, Inc.
  */
 
+#include <string.h>
 #include <rte_log.h>
+#include <rte_kvargs.h>
+#include <rte_devargs.h>
 
 #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;