xref: /dpdk/drivers/common/sfc_efx/sfc_efx.c (revision f33e8c0e4a80c1456987f96c1ce448d65e7d6dfb)
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