xref: /dpdk/drivers/raw/ifpga/rte_pmd_ifpga.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2021 Intel Corporation
3  */
4 
5 #include <rte_pci.h>
6 #include <rte_bus_pci.h>
7 #include <rte_rawdev.h>
8 #include <rte_rawdev_pmd.h>
9 #include "rte_pmd_ifpga.h"
10 #include "ifpga_rawdev.h"
11 #include "base/ifpga_api.h"
12 #include "base/ifpga_sec_mgr.h"
13 
14 
15 int
16 rte_pmd_ifpga_get_dev_id(const char *pci_addr, uint16_t *dev_id)
17 {
18 	struct rte_pci_addr addr;
19 	struct rte_rawdev *rdev = NULL;
20 	char rdev_name[RTE_RAWDEV_NAME_MAX_LEN] = {0};
21 
22 	if (!pci_addr || !dev_id) {
23 		IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid.");
24 		return -EINVAL;
25 	}
26 
27 	if (strnlen(pci_addr, PCI_PRI_STR_SIZE) == PCI_PRI_STR_SIZE) {
28 		IFPGA_RAWDEV_PMD_ERR("PCI address is too long.");
29 		return -EINVAL;
30 	}
31 
32 	if (rte_pci_addr_parse(pci_addr, &addr)) {
33 		IFPGA_RAWDEV_PMD_ERR("PCI address %s is invalid.", pci_addr);
34 		return -EINVAL;
35 	}
36 
37 	snprintf(rdev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x",
38 		addr.bus, addr.devid, addr.function);
39 	rdev = rte_rawdev_pmd_get_named_dev(rdev_name);
40 	if (!rdev) {
41 		IFPGA_RAWDEV_PMD_DEBUG("%s is not probed by ifpga driver.",
42 			pci_addr);
43 		return -ENODEV;
44 	}
45 	*dev_id = rdev->dev_id;
46 
47 	return 0;
48 }
49 
50 static struct rte_rawdev *
51 get_rte_rawdev(uint16_t dev_id)
52 {
53 	struct rte_rawdev *dev = NULL;
54 
55 	if (dev_id >= RTE_RAWDEV_MAX_DEVS)
56 		return NULL;
57 
58 	dev = &rte_rawdevs[dev_id];
59 	if (dev->attached == RTE_RAWDEV_ATTACHED)
60 		return dev;
61 
62 	return NULL;
63 }
64 
65 static struct opae_adapter *
66 get_opae_adapter(uint16_t dev_id)
67 {
68 	struct rte_rawdev *dev = NULL;
69 	struct opae_adapter *adapter = NULL;
70 
71 	dev = get_rte_rawdev(dev_id);
72 	if (!dev) {
73 		IFPGA_RAWDEV_PMD_ERR("Device ID %u is invalid.", dev_id);
74 		return NULL;
75 	}
76 
77 	adapter = ifpga_rawdev_get_priv(dev);
78 	if (!adapter) {
79 		IFPGA_RAWDEV_PMD_ERR("Adapter is not registered.");
80 		return NULL;
81 	}
82 
83 	return adapter;
84 }
85 
86 static opae_share_data *
87 get_share_data(struct opae_adapter *adapter)
88 {
89 	opae_share_data *sd = NULL;
90 
91 	if (!adapter)
92 		return NULL;
93 
94 	sd = (opae_share_data *)adapter->shm.ptr;
95 	if (!sd) {
96 		IFPGA_RAWDEV_PMD_ERR("Share data is not initialized.");
97 		return NULL;
98 	}
99 
100 	return sd;
101 }
102 
103 int
104 rte_pmd_ifpga_get_rsu_status(uint16_t dev_id, uint32_t *stat, uint32_t *prog)
105 {
106 	struct opae_adapter *adapter = NULL;
107 	opae_share_data *sd = NULL;
108 
109 	adapter = get_opae_adapter(dev_id);
110 	if (!adapter)
111 		return -ENODEV;
112 
113 	sd = get_share_data(adapter);
114 	if (!sd)
115 		return -ENOMEM;
116 
117 	if (stat)
118 		*stat = IFPGA_RSU_GET_STAT(sd->rsu_stat);
119 	if (prog)
120 		*prog = IFPGA_RSU_GET_PROG(sd->rsu_stat);
121 
122 	return 0;
123 }
124 
125 int
126 rte_pmd_ifpga_set_rsu_status(uint16_t dev_id, uint32_t stat, uint32_t prog)
127 {
128 	struct opae_adapter *adapter = NULL;
129 	opae_share_data *sd = NULL;
130 
131 	adapter = get_opae_adapter(dev_id);
132 	if (!adapter)
133 		return -ENODEV;
134 
135 	sd = get_share_data(adapter);
136 	if (!sd)
137 		return -ENOMEM;
138 
139 	sd->rsu_stat = IFPGA_RSU_STATUS(stat, prog);
140 
141 	return 0;
142 }
143 
144 static int
145 ifpga_is_rebooting(struct opae_adapter *adapter)
146 {
147 	opae_share_data *sd = NULL;
148 
149 	sd = get_share_data(adapter);
150 	if (!sd)
151 		return 1;
152 
153 	if (IFPGA_RSU_GET_STAT(sd->rsu_stat) == IFPGA_RSU_REBOOT) {
154 		IFPGA_RAWDEV_PMD_WARN("Reboot is in progress.");
155 		return 1;
156 	}
157 
158 	return 0;
159 }
160 
161 static int
162 get_common_property(struct opae_adapter *adapter,
163 	rte_pmd_ifpga_common_prop *prop)
164 {
165 	struct ifpga_fme_hw *fme = NULL;
166 	struct opae_board_info *info = NULL;
167 	struct feature_prop fp;
168 	struct uuid pr_id;
169 	int ret = 0;
170 
171 	if (!adapter || !prop)
172 		return -EINVAL;
173 
174 	if (!adapter->mgr || !adapter->mgr->data) {
175 		IFPGA_RAWDEV_PMD_ERR("Manager is not registered.");
176 		return -ENODEV;
177 	}
178 
179 	fme = adapter->mgr->data;
180 	fp.feature_id = FME_FEATURE_ID_HEADER;
181 	fp.prop_id = FME_HDR_PROP_PORTS_NUM;
182 	ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
183 	if (ret) {
184 		IFPGA_RAWDEV_PMD_ERR("Failed to get port number.");
185 		return ret;
186 	}
187 	prop->num_ports = fp.data;
188 
189 	fp.prop_id = FME_HDR_PROP_BITSTREAM_ID;
190 	ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
191 	if (ret) {
192 		IFPGA_RAWDEV_PMD_ERR("Failed to get bitstream ID.");
193 		return ret;
194 	}
195 	prop->bitstream_id = fp.data;
196 
197 	fp.prop_id = FME_HDR_PROP_BITSTREAM_METADATA;
198 	ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
199 	if (ret) {
200 		IFPGA_RAWDEV_PMD_ERR("Failed to get bitstream metadata.");
201 		return ret;
202 	}
203 	prop->bitstream_metadata = fp.data;
204 
205 	ret = opae_mgr_get_uuid(adapter->mgr, &pr_id);
206 	if (ret) {
207 		IFPGA_RAWDEV_PMD_ERR("Failed to get PR ID.");
208 		return ret;
209 	}
210 	memcpy(prop->pr_id.b, pr_id.b, sizeof(rte_pmd_ifpga_uuid));
211 
212 	ret = opae_mgr_get_board_info(adapter->mgr, &info);
213 	if (ret) {
214 		IFPGA_RAWDEV_PMD_ERR("Failed to get board info.");
215 		return ret;
216 	}
217 	prop->boot_page = info->boot_page;
218 	prop->bmc_version = info->max10_version;
219 	prop->bmc_nios_version = info->nios_fw_version;
220 
221 	return 0;
222 }
223 
224 static int
225 get_port_property(struct opae_adapter *adapter, uint16_t port,
226 	rte_pmd_ifpga_port_prop *prop)
227 {
228 	struct ifpga_fme_hw *fme = NULL;
229 	struct feature_prop fp;
230 	struct opae_accelerator *acc = NULL;
231 	struct uuid afu_id;
232 	int ret = 0;
233 
234 	if (!adapter || !prop)
235 		return -EINVAL;
236 
237 	if (!adapter->mgr || !adapter->mgr->data) {
238 		IFPGA_RAWDEV_PMD_ERR("Manager is not registered.");
239 		return -ENODEV;
240 	}
241 
242 	fme = adapter->mgr->data;
243 	fp.feature_id = FME_FEATURE_ID_HEADER;
244 	fp.prop_id = FME_HDR_PROP_PORT_TYPE;
245 	fp.data = port;
246 	fp.data <<= 32;
247 	ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
248 	if (ret)
249 		return ret;
250 	prop->type = fp.data & 0xffffffff;
251 
252 	if (prop->type == 0) {
253 		acc = opae_adapter_get_acc(adapter, port);
254 		ret = opae_acc_get_uuid(acc, &afu_id);
255 		if (ret) {
256 			IFPGA_RAWDEV_PMD_ERR("Failed to get port%u AFU ID.",
257 				port);
258 			return ret;
259 		}
260 		memcpy(prop->afu_id.b, afu_id.b, sizeof(rte_pmd_ifpga_uuid));
261 	}
262 
263 	return 0;
264 }
265 
266 int
267 rte_pmd_ifpga_get_property(uint16_t dev_id, rte_pmd_ifpga_prop *prop)
268 {
269 	struct opae_adapter *adapter = NULL;
270 	uint32_t i = 0;
271 	int ret = 0;
272 
273 	adapter = get_opae_adapter(dev_id);
274 	if (!adapter)
275 		return -ENODEV;
276 
277 	opae_adapter_lock(adapter, -1);
278 	if (ifpga_is_rebooting(adapter)) {
279 		ret = -EBUSY;
280 		goto unlock_dev;
281 	}
282 
283 	ret = get_common_property(adapter, &prop->common);
284 	if (ret) {
285 		ret = -EIO;
286 		goto unlock_dev;
287 	}
288 
289 	for (i = 0; i < prop->common.num_ports; i++) {
290 		ret = get_port_property(adapter, i, &prop->port[i]);
291 		if (ret) {
292 			ret = -EIO;
293 			break;
294 		}
295 	}
296 
297 unlock_dev:
298 	opae_adapter_unlock(adapter);
299 	return ret;
300 }
301 
302 int
303 rte_pmd_ifpga_get_phy_info(uint16_t dev_id, rte_pmd_ifpga_phy_info *info)
304 {
305 	struct opae_adapter *adapter = NULL;
306 	struct opae_retimer_info rtm_info;
307 	struct opae_retimer_status rtm_status;
308 	int ret = 0;
309 
310 	adapter = get_opae_adapter(dev_id);
311 	if (!adapter)
312 		return -ENODEV;
313 
314 	opae_adapter_lock(adapter, -1);
315 	if (ifpga_is_rebooting(adapter)) {
316 		ret = -EBUSY;
317 		goto unlock_dev;
318 	}
319 
320 	ret = opae_manager_get_retimer_info(adapter->mgr, &rtm_info);
321 	if (ret) {
322 		IFPGA_RAWDEV_PMD_ERR("Failed to get retimer info.");
323 		ret = -EIO;
324 		goto unlock_dev;
325 	}
326 	info->num_retimers = rtm_info.nums_retimer;
327 
328 	ret = opae_manager_get_retimer_status(adapter->mgr, &rtm_status);
329 	if (ret) {
330 		IFPGA_RAWDEV_PMD_ERR("Failed to get retimer status.");
331 		ret = -EIO;
332 		goto unlock_dev;
333 	}
334 	info->link_speed = rtm_status.speed;
335 	info->link_status = rtm_status.line_link_bitmap;
336 
337 unlock_dev:
338 	opae_adapter_unlock(adapter);
339 	return ret;
340 }
341 
342 int
343 rte_pmd_ifpga_update_flash(uint16_t dev_id, const char *image,
344 	uint64_t *status)
345 {
346 	struct opae_adapter *adapter = NULL;
347 
348 	adapter = get_opae_adapter(dev_id);
349 	if (!adapter)
350 		return -ENODEV;
351 
352 	return opae_mgr_update_flash(adapter->mgr, image, status);
353 }
354 
355 int
356 rte_pmd_ifpga_stop_update(uint16_t dev_id, int force)
357 {
358 	struct opae_adapter *adapter = NULL;
359 
360 	adapter = get_opae_adapter(dev_id);
361 	if (!adapter)
362 		return -ENODEV;
363 
364 	return opae_mgr_stop_flash_update(adapter->mgr, force);
365 }
366 
367 int
368 rte_pmd_ifpga_reboot_try(uint16_t dev_id)
369 {
370 	struct opae_adapter *adapter = NULL;
371 	opae_share_data *sd = NULL;
372 
373 	adapter = get_opae_adapter(dev_id);
374 	if (!adapter)
375 		return -ENODEV;
376 
377 	sd = get_share_data(adapter);
378 	if (!sd)
379 		return -ENOMEM;
380 
381 	opae_adapter_lock(adapter, -1);
382 	if (IFPGA_RSU_GET_STAT(sd->rsu_stat) != IFPGA_RSU_IDLE) {
383 		opae_adapter_unlock(adapter);
384 		IFPGA_RAWDEV_PMD_WARN("Update or reboot is in progress.");
385 		return -EBUSY;
386 	}
387 	sd->rsu_stat = IFPGA_RSU_STATUS(IFPGA_RSU_REBOOT, 0);
388 	opae_adapter_unlock(adapter);
389 
390 	return 0;
391 }
392 
393 int
394 rte_pmd_ifpga_reload(uint16_t dev_id, int type, int page)
395 {
396 	struct opae_adapter *adapter = NULL;
397 
398 	adapter = get_opae_adapter(dev_id);
399 	if (!adapter)
400 		return -ENODEV;
401 
402 	return opae_mgr_reload(adapter->mgr, type, page);
403 }
404 
405 const struct rte_pci_bus *
406 rte_pmd_ifpga_get_pci_bus(void)
407 {
408 	return ifpga_get_pci_bus();
409 }
410 
411 int
412 rte_pmd_ifpga_partial_reconfigure(uint16_t dev_id, int port, const char *file)
413 {
414 	struct rte_rawdev *dev = NULL;
415 
416 	dev = get_rte_rawdev(dev_id);
417 	if (!dev) {
418 		IFPGA_RAWDEV_PMD_ERR("Device ID %u is invalid.", dev_id);
419 		return -EINVAL;
420 	}
421 
422 	return ifpga_rawdev_partial_reconfigure(dev, port, file);
423 }
424 
425 void
426 rte_pmd_ifpga_cleanup(void)
427 {
428 	ifpga_rawdev_cleanup();
429 }
430