xref: /dpdk/drivers/crypto/ionic/ionic_crypto_vdev.c (revision 25c896ea6c406f9b4c5c2fec111a34103dbbec5d)
14610ac93SAndrew Boyer /* SPDX-License-Identifier: BSD-3-Clause
24610ac93SAndrew Boyer  * Copyright 2021-2024 Advanced Micro Devices, Inc.
34610ac93SAndrew Boyer  */
44610ac93SAndrew Boyer 
54610ac93SAndrew Boyer #include <stdint.h>
64610ac93SAndrew Boyer #include <errno.h>
74610ac93SAndrew Boyer 
84610ac93SAndrew Boyer #include <rte_errno.h>
94610ac93SAndrew Boyer #include <rte_common.h>
104610ac93SAndrew Boyer #include <rte_log.h>
114610ac93SAndrew Boyer #include <rte_eal.h>
124610ac93SAndrew Boyer #include <bus_vdev_driver.h>
134610ac93SAndrew Boyer #include <rte_dev.h>
144610ac93SAndrew Boyer #include <rte_string_fns.h>
154610ac93SAndrew Boyer 
164610ac93SAndrew Boyer #include "ionic_crypto.h"
174610ac93SAndrew Boyer 
184610ac93SAndrew Boyer #define IOCPT_VDEV_DEV_BAR          0
194610ac93SAndrew Boyer #define IOCPT_VDEV_INTR_CTL_BAR     1
204610ac93SAndrew Boyer #define IOCPT_VDEV_INTR_CFG_BAR     2
214610ac93SAndrew Boyer #define IOCPT_VDEV_DB_BAR           3
224610ac93SAndrew Boyer #define IOCPT_VDEV_BARS_MAX         4
234610ac93SAndrew Boyer 
244610ac93SAndrew Boyer #define IOCPT_VDEV_DEV_INFO_REGS_OFFSET      0x0000
254610ac93SAndrew Boyer #define IOCPT_VDEV_DEV_CMD_REGS_OFFSET       0x0800
264610ac93SAndrew Boyer 
27*25c896eaSAndrew Boyer #define IOCPT_VDEV_FW_WAIT_US       1000     /* 1ms */
28*25c896eaSAndrew Boyer #define IOCPT_VDEV_FW_WAIT_MAX      5000     /* 5s */
29*25c896eaSAndrew Boyer 
304610ac93SAndrew Boyer static int
iocpt_vdev_setup_bars(struct iocpt_dev * dev)314610ac93SAndrew Boyer iocpt_vdev_setup_bars(struct iocpt_dev *dev)
324610ac93SAndrew Boyer {
33*25c896eaSAndrew Boyer 	struct iocpt_dev_bars *bars = &dev->bars;
34*25c896eaSAndrew Boyer 	uint8_t *bar0_base;
35*25c896eaSAndrew Boyer 	uint32_t fw_waits = 0;
36*25c896eaSAndrew Boyer 	uint8_t fw;
37*25c896eaSAndrew Boyer 
384610ac93SAndrew Boyer 	IOCPT_PRINT_CALL();
394610ac93SAndrew Boyer 
40*25c896eaSAndrew Boyer 	/* BAR0: dev_cmd */
41*25c896eaSAndrew Boyer 	bar0_base = bars->bar[IOCPT_VDEV_DEV_BAR].vaddr;
42*25c896eaSAndrew Boyer 	dev->dev_info = (union iocpt_dev_info_regs *)
43*25c896eaSAndrew Boyer 		&bar0_base[IOCPT_VDEV_DEV_INFO_REGS_OFFSET];
44*25c896eaSAndrew Boyer 	dev->dev_cmd = (union iocpt_dev_cmd_regs *)
45*25c896eaSAndrew Boyer 		&bar0_base[IOCPT_VDEV_DEV_CMD_REGS_OFFSET];
46*25c896eaSAndrew Boyer 
47*25c896eaSAndrew Boyer 	/* BAR1: interrupts */
48*25c896eaSAndrew Boyer 	dev->intr_ctrl = (void *)bars->bar[IOCPT_VDEV_INTR_CTL_BAR].vaddr;
49*25c896eaSAndrew Boyer 
50*25c896eaSAndrew Boyer 	/* BAR3: doorbells */
51*25c896eaSAndrew Boyer 	dev->db_pages = (void *)bars->bar[IOCPT_VDEV_DB_BAR].vaddr;
52*25c896eaSAndrew Boyer 
53*25c896eaSAndrew Boyer 	/* Wait for the FW to indicate readiness */
54*25c896eaSAndrew Boyer 	while (1) {
55*25c896eaSAndrew Boyer 		fw = ioread8(&dev->dev_info->fw_status);
56*25c896eaSAndrew Boyer 		if ((fw & IOCPT_FW_STS_F_RUNNING) != 0)
57*25c896eaSAndrew Boyer 			break;
58*25c896eaSAndrew Boyer 
59*25c896eaSAndrew Boyer 		if (fw_waits > IOCPT_VDEV_FW_WAIT_MAX) {
60*25c896eaSAndrew Boyer 			IOCPT_PRINT(ERR, "Firmware readiness bit not set");
61*25c896eaSAndrew Boyer 			return -ETIMEDOUT;
62*25c896eaSAndrew Boyer 		}
63*25c896eaSAndrew Boyer 
64*25c896eaSAndrew Boyer 		fw_waits++;
65*25c896eaSAndrew Boyer 		rte_delay_us_block(IOCPT_VDEV_FW_WAIT_US);
66*25c896eaSAndrew Boyer 	}
67*25c896eaSAndrew Boyer 	IOCPT_PRINT(DEBUG, "Firmware ready (%u waits)", fw_waits);
68*25c896eaSAndrew Boyer 
694610ac93SAndrew Boyer 	dev->name = rte_vdev_device_name(dev->bus_dev);
704610ac93SAndrew Boyer 
714610ac93SAndrew Boyer 	return 0;
724610ac93SAndrew Boyer }
734610ac93SAndrew Boyer 
744610ac93SAndrew Boyer static void
iocpt_vdev_unmap_bars(struct iocpt_dev * dev)754610ac93SAndrew Boyer iocpt_vdev_unmap_bars(struct iocpt_dev *dev)
764610ac93SAndrew Boyer {
774610ac93SAndrew Boyer 	struct iocpt_dev_bars *bars = &dev->bars;
784610ac93SAndrew Boyer 	uint32_t i;
794610ac93SAndrew Boyer 
804610ac93SAndrew Boyer 	for (i = 0; i < IOCPT_VDEV_BARS_MAX; i++)
814610ac93SAndrew Boyer 		ionic_uio_rel_rsrc(dev->name, i, &bars->bar[i]);
824610ac93SAndrew Boyer }
834610ac93SAndrew Boyer 
844610ac93SAndrew Boyer static uint8_t iocpt_vdev_driver_id;
854610ac93SAndrew Boyer static const struct iocpt_dev_intf iocpt_vdev_intf = {
864610ac93SAndrew Boyer 	.setup_bars = iocpt_vdev_setup_bars,
874610ac93SAndrew Boyer 	.unmap_bars = iocpt_vdev_unmap_bars,
884610ac93SAndrew Boyer };
894610ac93SAndrew Boyer 
904610ac93SAndrew Boyer static int
iocpt_vdev_probe(struct rte_vdev_device * vdev)914610ac93SAndrew Boyer iocpt_vdev_probe(struct rte_vdev_device *vdev)
924610ac93SAndrew Boyer {
934610ac93SAndrew Boyer 	struct iocpt_dev_bars bars = {};
944610ac93SAndrew Boyer 	const char *name = rte_vdev_device_name(vdev);
954610ac93SAndrew Boyer 	unsigned int i;
964610ac93SAndrew Boyer 
974610ac93SAndrew Boyer 	IOCPT_PRINT(NOTICE, "Initializing device %s%s", name,
984610ac93SAndrew Boyer 		rte_eal_process_type() == RTE_PROC_SECONDARY ?
994610ac93SAndrew Boyer 			" [SECONDARY]" : "");
1004610ac93SAndrew Boyer 
1014610ac93SAndrew Boyer 	ionic_uio_scan_mcrypt_devices();
1024610ac93SAndrew Boyer 
1034610ac93SAndrew Boyer 	for (i = 0; i < IOCPT_VDEV_BARS_MAX; i++)
1044610ac93SAndrew Boyer 		ionic_uio_get_rsrc(name, i, &bars.bar[i]);
1054610ac93SAndrew Boyer 
1064610ac93SAndrew Boyer 	bars.num_bars = IOCPT_VDEV_BARS_MAX;
1074610ac93SAndrew Boyer 
1084610ac93SAndrew Boyer 	return iocpt_probe((void *)vdev, &vdev->device,
1094610ac93SAndrew Boyer 			&bars, &iocpt_vdev_intf,
1104610ac93SAndrew Boyer 			iocpt_vdev_driver_id, rte_socket_id());
1114610ac93SAndrew Boyer }
1124610ac93SAndrew Boyer 
1134610ac93SAndrew Boyer static int
iocpt_vdev_remove(struct rte_vdev_device * vdev)1144610ac93SAndrew Boyer iocpt_vdev_remove(struct rte_vdev_device *vdev)
1154610ac93SAndrew Boyer {
1164610ac93SAndrew Boyer 	return iocpt_remove(&vdev->device);
1174610ac93SAndrew Boyer }
1184610ac93SAndrew Boyer 
1194610ac93SAndrew Boyer static struct rte_vdev_driver rte_vdev_iocpt_pmd = {
1204610ac93SAndrew Boyer 	.probe = iocpt_vdev_probe,
1214610ac93SAndrew Boyer 	.remove = iocpt_vdev_remove,
1224610ac93SAndrew Boyer };
1234610ac93SAndrew Boyer 
1244610ac93SAndrew Boyer static struct cryptodev_driver rte_vdev_iocpt_drv;
1254610ac93SAndrew Boyer 
1264610ac93SAndrew Boyer RTE_PMD_REGISTER_VDEV(crypto_ionic, rte_vdev_iocpt_pmd);
1274610ac93SAndrew Boyer RTE_PMD_REGISTER_CRYPTO_DRIVER(rte_vdev_iocpt_drv, rte_vdev_iocpt_pmd.driver,
1284610ac93SAndrew Boyer 		iocpt_vdev_driver_id);
129