xref: /dpdk/drivers/net/ionic/ionic_dev_pci.c (revision de1f01a8eabd1da08d85e77ff99ba85e03cfd1ad)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2018-2022 Advanced Micro Devices, Inc.
3  */
4 
5 #include <stdio.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <stdint.h>
9 
10 #include <rte_common.h>
11 #include <rte_interrupts.h>
12 #include <rte_log.h>
13 #include <rte_pci.h>
14 #include <bus_pci_driver.h>
15 #include <rte_eal.h>
16 #include <ethdev_pci.h>
17 #include <rte_dev.h>
18 #include <rte_kvargs.h>
19 
20 #include "ionic.h"
21 #include "ionic_if.h"
22 #include "ionic_dev.h"
23 #include "ionic_ethdev.h"
24 #include "ionic_logs.h"
25 
26 static const struct rte_pci_id pci_id_ionic_map[] = {
27 	{ RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_PF) },
28 	{ RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_VF) },
29 	{ RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_MGMT) },
30 	{ .vendor_id = 0, /* sentinel */ },
31 };
32 
33 static int
34 ionic_pci_setup(struct ionic_adapter *adapter)
35 {
36 	struct ionic_dev_bar *bar = adapter->bars.bar;
37 	unsigned int num_bars = adapter->bars.num_bars;
38 	struct ionic_dev *idev = &adapter->idev;
39 	struct rte_pci_device *bus_dev = adapter->bus_dev;
40 	uint32_t sig;
41 	uint8_t *bar0_base;
42 	unsigned int i;
43 
44 	/* BAR0: dev_cmd and interrupts */
45 	if (num_bars < 1) {
46 		IONIC_PRINT(ERR, "No bars found, aborting\n");
47 		return -EFAULT;
48 	}
49 
50 	if (bar->len < IONIC_BAR0_SIZE) {
51 		IONIC_PRINT(ERR,
52 			"Resource bar size %lu too small, aborting\n",
53 			bar->len);
54 		return -EFAULT;
55 	}
56 
57 	bar0_base = bar->vaddr;
58 	idev->dev_info = (union ionic_dev_info_regs *)
59 		&bar0_base[IONIC_BAR0_DEV_INFO_REGS_OFFSET];
60 	idev->dev_cmd = (union ionic_dev_cmd_regs *)
61 		&bar0_base[IONIC_BAR0_DEV_CMD_REGS_OFFSET];
62 	idev->intr_status = (struct ionic_intr_status *)
63 		&bar0_base[IONIC_BAR0_INTR_STATUS_OFFSET];
64 	idev->intr_ctrl = (struct ionic_intr *)
65 		&bar0_base[IONIC_BAR0_INTR_CTRL_OFFSET];
66 
67 	sig = ioread32(&idev->dev_info->signature);
68 	if (sig != IONIC_DEV_INFO_SIGNATURE) {
69 		IONIC_PRINT(ERR, "Incompatible firmware signature %#x",
70 			sig);
71 		return -EFAULT;
72 	}
73 
74 	for (i = 0; i < IONIC_DEVINFO_FWVERS_BUFLEN; i++)
75 		adapter->fw_version[i] =
76 			ioread8(&idev->dev_info->fw_version[i]);
77 	adapter->fw_version[IONIC_DEVINFO_FWVERS_BUFLEN - 1] = '\0';
78 
79 	adapter->name = bus_dev->device.name;
80 
81 	IONIC_PRINT(DEBUG, "%s firmware version: %s",
82 		adapter->name, adapter->fw_version);
83 
84 	/* BAR1: doorbells */
85 	bar++;
86 	if (num_bars < IONIC_BARS_MIN) {
87 		IONIC_PRINT(ERR, "Doorbell bar missing, aborting\n");
88 		return -EFAULT;
89 	}
90 
91 	idev->db_pages = bar->vaddr;
92 
93 	return 0;
94 }
95 
96 const char *ionic_pci_devargs_arr[] = {
97 	PMD_IONIC_CMB_KVARG,
98 	NULL,
99 };
100 
101 static int
102 ionic_pci_devarg_cmb(const char *key __rte_unused, const char *val, void *arg)
103 {
104 	struct ionic_adapter *adapter = arg;
105 
106 	if (!strcmp(val, "1")) {
107 		IONIC_PRINT(NOTICE, "%s enabled", PMD_IONIC_CMB_KVARG);
108 		adapter->q_in_cmb = true;
109 	} else if (!strcmp(val, "0")) {
110 		IONIC_PRINT(DEBUG, "%s disabled (default)",
111 			PMD_IONIC_CMB_KVARG);
112 	} else {
113 		IONIC_PRINT(ERR, "%s=%s invalid, use 1 or 0",
114 			PMD_IONIC_CMB_KVARG, val);
115 		return -ERANGE;
116 	}
117 
118 	return 0;
119 }
120 
121 static int
122 ionic_pci_devargs(struct ionic_adapter *adapter, struct rte_devargs *devargs)
123 {
124 	struct rte_kvargs *kvlist;
125 	int err = 0;
126 
127 	if (!devargs)
128 		return 0;
129 
130 	kvlist = rte_kvargs_parse(devargs->args, ionic_pci_devargs_arr);
131 	if (!kvlist) {
132 		IONIC_PRINT(ERR, "Couldn't parse args '%s'", devargs->args);
133 		return -EINVAL;
134 	}
135 
136 	if (rte_kvargs_count(kvlist, PMD_IONIC_CMB_KVARG) == 1) {
137 		err = rte_kvargs_process(kvlist, PMD_IONIC_CMB_KVARG,
138 				ionic_pci_devarg_cmb, adapter);
139 		if (err < 0)
140 			goto free_kvlist;
141 	}
142 
143 free_kvlist:
144 	rte_kvargs_free(kvlist);
145 	return err;
146 }
147 
148 static void
149 ionic_pci_copy_bus_info(struct ionic_adapter *adapter,
150 	struct rte_eth_dev *eth_dev)
151 {
152 	rte_eth_copy_pci_info(eth_dev, adapter->bus_dev);
153 }
154 
155 static int
156 ionic_pci_configure_intr(struct ionic_adapter *adapter)
157 {
158 	struct rte_pci_device *pci_dev =
159 		(struct rte_pci_device *)(adapter->bus_dev);
160 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
161 	int err;
162 
163 	IONIC_PRINT(ERR, "Configuring %u intrs", adapter->nintrs);
164 
165 	if (rte_intr_efd_enable(intr_handle, adapter->nintrs)) {
166 		IONIC_PRINT(ERR, "Fail to create eventfd");
167 		return -1;
168 	}
169 
170 	if (rte_intr_dp_is_en(intr_handle)) {
171 		IONIC_PRINT(NOTICE,
172 			"Packet I/O interrupt on datapath is enabled");
173 		if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
174 						adapter->nintrs)) {
175 			IONIC_PRINT(ERR, "Failed to allocate %u vectors",
176 						adapter->nintrs);
177 			return -ENOMEM;
178 		}
179 	}
180 
181 	err = rte_intr_callback_register(intr_handle,
182 		ionic_dev_interrupt_handler,
183 		adapter);
184 	if (err) {
185 		IONIC_PRINT(ERR,
186 			"Failure registering interrupts handler (%d)", err);
187 		return err;
188 	}
189 
190 	/* enable intr mapping */
191 	err = rte_intr_enable(intr_handle);
192 	if (err) {
193 		IONIC_PRINT(ERR, "Failure enabling interrupts (%d)", err);
194 		return err;
195 	}
196 
197 	return 0;
198 }
199 
200 static void
201 ionic_pci_unconfigure_intr(struct ionic_adapter *adapter)
202 {
203 	struct rte_pci_device *pci_dev =
204 		(struct rte_pci_device *)(adapter->bus_dev);
205 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
206 
207 	rte_intr_disable(intr_handle);
208 
209 	rte_intr_callback_unregister(intr_handle,
210 		ionic_dev_interrupt_handler,
211 		adapter);
212 }
213 
214 static const struct ionic_dev_intf ionic_pci_intf = {
215 	.setup = ionic_pci_setup,
216 	.devargs = ionic_pci_devargs,
217 	.copy_bus_info = ionic_pci_copy_bus_info,
218 	.configure_intr = ionic_pci_configure_intr,
219 	.unconfigure_intr = ionic_pci_unconfigure_intr,
220 };
221 
222 static int
223 eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
224 		struct rte_pci_device *pci_dev)
225 {
226 	struct rte_mem_resource *resource;
227 	struct ionic_bars bars;
228 	unsigned long i;
229 
230 	IONIC_PRINT(NOTICE, "Initializing device %s %s",
231 		pci_dev->device.name,
232 		rte_eal_process_type() == RTE_PROC_SECONDARY ?
233 		"[SECONDARY]" : "");
234 
235 	bars.num_bars = 0;
236 	for (i = 0; i < PCI_MAX_RESOURCE && i < IONIC_BARS_MAX; i++) {
237 		resource = &pci_dev->mem_resource[i];
238 		if (resource->phys_addr == 0 || resource->len == 0)
239 			continue;
240 
241 		bars.bar[bars.num_bars].vaddr = resource->addr;
242 		bars.bar[bars.num_bars].bus_addr = resource->phys_addr;
243 		bars.bar[bars.num_bars].len = resource->len;
244 		bars.num_bars++;
245 	}
246 
247 	return eth_ionic_dev_probe((void *)pci_dev,
248 			&pci_dev->device,
249 			&bars,
250 			&ionic_pci_intf,
251 			pci_dev->id.device_id,
252 			pci_dev->id.vendor_id);
253 }
254 
255 static int
256 eth_ionic_pci_remove(struct rte_pci_device *pci_dev)
257 {
258 	return eth_ionic_dev_remove(&pci_dev->device);
259 }
260 
261 static struct rte_pci_driver rte_pci_ionic_pmd = {
262 	.id_table = pci_id_ionic_map,
263 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
264 			RTE_PCI_DRV_WC_ACTIVATE,
265 	.probe = eth_ionic_pci_probe,
266 	.remove = eth_ionic_pci_remove,
267 };
268 
269 RTE_PMD_REGISTER_PCI(net_ionic_pci, rte_pci_ionic_pmd);
270 RTE_PMD_REGISTER_PCI_TABLE(net_ionic_pci, pci_id_ionic_map);
271 RTE_PMD_REGISTER_KMOD_DEP(net_ionic_pci, "* igb_uio | uio_pci_generic | vfio-pci");
272 RTE_PMD_REGISTER_PARAM_STRING(net_ionic_pci,
273 	PMD_IONIC_CMB_KVARG "=<0|1>"
274 );
275