xref: /dpdk/drivers/crypto/ionic/ionic_crypto_main.c (revision a677112db0473dcfc1f8d24bf41c1c3b074f7718)
14610ac93SAndrew Boyer /* SPDX-License-Identifier: BSD-3-Clause
24610ac93SAndrew Boyer  * Copyright 2021-2024 Advanced Micro Devices, Inc.
34610ac93SAndrew Boyer  */
44610ac93SAndrew Boyer 
54610ac93SAndrew Boyer #include <inttypes.h>
64610ac93SAndrew Boyer 
74610ac93SAndrew Boyer #include <rte_common.h>
84610ac93SAndrew Boyer #include <rte_malloc.h>
94610ac93SAndrew Boyer #include <rte_bitops.h>
104610ac93SAndrew Boyer 
114610ac93SAndrew Boyer #include "ionic_crypto.h"
124610ac93SAndrew Boyer 
13*a677112dSAndrew Boyer static const struct rte_memzone *
14*a677112dSAndrew Boyer iocpt_dma_zone_reserve(const char *type_name, uint16_t qid, size_t size,
15*a677112dSAndrew Boyer 			unsigned int align, int socket_id)
16*a677112dSAndrew Boyer {
17*a677112dSAndrew Boyer 	char zone_name[RTE_MEMZONE_NAMESIZE];
18*a677112dSAndrew Boyer 	const struct rte_memzone *mz;
19*a677112dSAndrew Boyer 	int err;
20*a677112dSAndrew Boyer 
21*a677112dSAndrew Boyer 	err = snprintf(zone_name, sizeof(zone_name),
22*a677112dSAndrew Boyer 			"iocpt_%s_%u", type_name, qid);
23*a677112dSAndrew Boyer 	if (err >= RTE_MEMZONE_NAMESIZE) {
24*a677112dSAndrew Boyer 		IOCPT_PRINT(ERR, "Name %s too long", type_name);
25*a677112dSAndrew Boyer 		return NULL;
26*a677112dSAndrew Boyer 	}
27*a677112dSAndrew Boyer 
28*a677112dSAndrew Boyer 	mz = rte_memzone_lookup(zone_name);
29*a677112dSAndrew Boyer 	if (mz != NULL)
30*a677112dSAndrew Boyer 		return mz;
31*a677112dSAndrew Boyer 
32*a677112dSAndrew Boyer 	return rte_memzone_reserve_aligned(zone_name, size, socket_id,
33*a677112dSAndrew Boyer 			RTE_MEMZONE_IOVA_CONTIG, align);
34*a677112dSAndrew Boyer }
35*a677112dSAndrew Boyer 
36*a677112dSAndrew Boyer static int
37*a677112dSAndrew Boyer iocpt_alloc_objs(struct iocpt_dev *dev)
38*a677112dSAndrew Boyer {
39*a677112dSAndrew Boyer 	int err;
40*a677112dSAndrew Boyer 
41*a677112dSAndrew Boyer 	IOCPT_PRINT(DEBUG, "Crypto: %s", dev->name);
42*a677112dSAndrew Boyer 
43*a677112dSAndrew Boyer 	dev->info_sz = RTE_ALIGN(sizeof(*dev->info), rte_mem_page_size());
44*a677112dSAndrew Boyer 	dev->info_z = iocpt_dma_zone_reserve("info", 0, dev->info_sz,
45*a677112dSAndrew Boyer 					IONIC_ALIGN, dev->socket_id);
46*a677112dSAndrew Boyer 	if (dev->info_z == NULL) {
47*a677112dSAndrew Boyer 		IOCPT_PRINT(ERR, "Cannot allocate dev info memory");
48*a677112dSAndrew Boyer 		err = -ENOMEM;
49*a677112dSAndrew Boyer 		goto err_out;
50*a677112dSAndrew Boyer 	}
51*a677112dSAndrew Boyer 
52*a677112dSAndrew Boyer 	dev->info = dev->info_z->addr;
53*a677112dSAndrew Boyer 	dev->info_pa = dev->info_z->iova;
54*a677112dSAndrew Boyer 
55*a677112dSAndrew Boyer 	return 0;
56*a677112dSAndrew Boyer 
57*a677112dSAndrew Boyer err_out:
58*a677112dSAndrew Boyer 	return err;
59*a677112dSAndrew Boyer }
60*a677112dSAndrew Boyer 
614610ac93SAndrew Boyer static int
624610ac93SAndrew Boyer iocpt_init(struct iocpt_dev *dev)
634610ac93SAndrew Boyer {
64*a677112dSAndrew Boyer 	int err;
65*a677112dSAndrew Boyer 
66*a677112dSAndrew Boyer 	/* Uses dev_cmds */
67*a677112dSAndrew Boyer 	err = iocpt_dev_init(dev, dev->info_pa);
68*a677112dSAndrew Boyer 	if (err != 0)
69*a677112dSAndrew Boyer 		return err;
70*a677112dSAndrew Boyer 
714610ac93SAndrew Boyer 	dev->state |= IOCPT_DEV_F_INITED;
724610ac93SAndrew Boyer 
734610ac93SAndrew Boyer 	return 0;
744610ac93SAndrew Boyer }
754610ac93SAndrew Boyer 
764610ac93SAndrew Boyer void
774610ac93SAndrew Boyer iocpt_configure(struct iocpt_dev *dev)
784610ac93SAndrew Boyer {
794610ac93SAndrew Boyer 	RTE_SET_USED(dev);
804610ac93SAndrew Boyer }
814610ac93SAndrew Boyer 
824610ac93SAndrew Boyer void
834610ac93SAndrew Boyer iocpt_deinit(struct iocpt_dev *dev)
844610ac93SAndrew Boyer {
854610ac93SAndrew Boyer 	IOCPT_PRINT_CALL();
864610ac93SAndrew Boyer 
874610ac93SAndrew Boyer 	if (!(dev->state & IOCPT_DEV_F_INITED))
884610ac93SAndrew Boyer 		return;
894610ac93SAndrew Boyer 
904610ac93SAndrew Boyer 	dev->state &= ~IOCPT_DEV_F_INITED;
914610ac93SAndrew Boyer }
924610ac93SAndrew Boyer 
93*a677112dSAndrew Boyer static void
94*a677112dSAndrew Boyer iocpt_free_objs(struct iocpt_dev *dev)
95*a677112dSAndrew Boyer {
96*a677112dSAndrew Boyer 	IOCPT_PRINT_CALL();
97*a677112dSAndrew Boyer 
98*a677112dSAndrew Boyer 	if (dev->info != NULL) {
99*a677112dSAndrew Boyer 		rte_memzone_free(dev->info_z);
100*a677112dSAndrew Boyer 		dev->info_z = NULL;
101*a677112dSAndrew Boyer 		dev->info = NULL;
102*a677112dSAndrew Boyer 		dev->info_pa = 0;
103*a677112dSAndrew Boyer 	}
104*a677112dSAndrew Boyer }
105*a677112dSAndrew Boyer 
1064610ac93SAndrew Boyer static int
1074610ac93SAndrew Boyer iocpt_devargs(struct rte_devargs *devargs, struct iocpt_dev *dev)
1084610ac93SAndrew Boyer {
1094610ac93SAndrew Boyer 	RTE_SET_USED(devargs);
1104610ac93SAndrew Boyer 	RTE_SET_USED(dev);
1114610ac93SAndrew Boyer 
1124610ac93SAndrew Boyer 	return 0;
1134610ac93SAndrew Boyer }
1144610ac93SAndrew Boyer 
1154610ac93SAndrew Boyer int
1164610ac93SAndrew Boyer iocpt_probe(void *bus_dev, struct rte_device *rte_dev,
1174610ac93SAndrew Boyer 	struct iocpt_dev_bars *bars, const struct iocpt_dev_intf *intf,
1184610ac93SAndrew Boyer 	uint8_t driver_id, uint8_t socket_id)
1194610ac93SAndrew Boyer {
1204610ac93SAndrew Boyer 	struct rte_cryptodev_pmd_init_params init_params = {
1214610ac93SAndrew Boyer 		"iocpt",
1224610ac93SAndrew Boyer 		sizeof(struct iocpt_dev),
1234610ac93SAndrew Boyer 		socket_id,
1244610ac93SAndrew Boyer 		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
1254610ac93SAndrew Boyer 	};
1264610ac93SAndrew Boyer 	struct rte_cryptodev *cdev;
1274610ac93SAndrew Boyer 	struct iocpt_dev *dev;
12825c896eaSAndrew Boyer 	uint32_t i, sig;
1294610ac93SAndrew Boyer 	int err;
1304610ac93SAndrew Boyer 
13125c896eaSAndrew Boyer 	/* Check structs (trigger error at compilation time) */
13225c896eaSAndrew Boyer 	iocpt_struct_size_checks();
13325c896eaSAndrew Boyer 
1344610ac93SAndrew Boyer 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1354610ac93SAndrew Boyer 		IOCPT_PRINT(ERR, "Multi-process not supported");
1364610ac93SAndrew Boyer 		err = -EPERM;
1374610ac93SAndrew Boyer 		goto err;
1384610ac93SAndrew Boyer 	}
1394610ac93SAndrew Boyer 
1404610ac93SAndrew Boyer 	cdev = rte_cryptodev_pmd_create(rte_dev->name, rte_dev, &init_params);
1414610ac93SAndrew Boyer 	if (cdev == NULL) {
1424610ac93SAndrew Boyer 		IOCPT_PRINT(ERR, "Out of memory");
1434610ac93SAndrew Boyer 		err = -ENOMEM;
1444610ac93SAndrew Boyer 		goto err;
1454610ac93SAndrew Boyer 	}
1464610ac93SAndrew Boyer 
1474610ac93SAndrew Boyer 	dev = cdev->data->dev_private;
1484610ac93SAndrew Boyer 	dev->crypto_dev = cdev;
1494610ac93SAndrew Boyer 	dev->bus_dev = bus_dev;
1504610ac93SAndrew Boyer 	dev->intf = intf;
1514610ac93SAndrew Boyer 	dev->driver_id = driver_id;
1524610ac93SAndrew Boyer 	dev->socket_id = socket_id;
1534610ac93SAndrew Boyer 
1544610ac93SAndrew Boyer 	for (i = 0; i < bars->num_bars; i++) {
1554610ac93SAndrew Boyer 		struct ionic_dev_bar *bar = &bars->bar[i];
1564610ac93SAndrew Boyer 
1574610ac93SAndrew Boyer 		IOCPT_PRINT(DEBUG,
1584610ac93SAndrew Boyer 			"bar[%u] = { .va = %p, .pa = %#jx, .len = %lu }",
1594610ac93SAndrew Boyer 			i, bar->vaddr, bar->bus_addr, bar->len);
1604610ac93SAndrew Boyer 		if (bar->vaddr == NULL) {
1614610ac93SAndrew Boyer 			IOCPT_PRINT(ERR, "Null bar found, aborting");
1624610ac93SAndrew Boyer 			err = -EFAULT;
1634610ac93SAndrew Boyer 			goto err_destroy_crypto_dev;
1644610ac93SAndrew Boyer 		}
1654610ac93SAndrew Boyer 
1664610ac93SAndrew Boyer 		dev->bars.bar[i].vaddr = bar->vaddr;
1674610ac93SAndrew Boyer 		dev->bars.bar[i].bus_addr = bar->bus_addr;
1684610ac93SAndrew Boyer 		dev->bars.bar[i].len = bar->len;
1694610ac93SAndrew Boyer 	}
1704610ac93SAndrew Boyer 	dev->bars.num_bars = bars->num_bars;
1714610ac93SAndrew Boyer 
1724610ac93SAndrew Boyer 	err = iocpt_devargs(rte_dev->devargs, dev);
1734610ac93SAndrew Boyer 	if (err != 0) {
1744610ac93SAndrew Boyer 		IOCPT_PRINT(ERR, "Cannot parse device arguments");
1754610ac93SAndrew Boyer 		goto err_destroy_crypto_dev;
1764610ac93SAndrew Boyer 	}
1774610ac93SAndrew Boyer 
1784610ac93SAndrew Boyer 	err = iocpt_setup_bars(dev);
1794610ac93SAndrew Boyer 	if (err != 0) {
1804610ac93SAndrew Boyer 		IOCPT_PRINT(ERR, "Cannot setup BARs: %d, aborting", err);
1814610ac93SAndrew Boyer 		goto err_destroy_crypto_dev;
1824610ac93SAndrew Boyer 	}
1834610ac93SAndrew Boyer 
18425c896eaSAndrew Boyer 	sig = ioread32(&dev->dev_info->signature);
18525c896eaSAndrew Boyer 	if (sig != IOCPT_DEV_INFO_SIGNATURE) {
18625c896eaSAndrew Boyer 		IOCPT_PRINT(ERR, "Incompatible firmware signature %#x", sig);
18725c896eaSAndrew Boyer 		err = -EFAULT;
18825c896eaSAndrew Boyer 		goto err_destroy_crypto_dev;
18925c896eaSAndrew Boyer 	}
19025c896eaSAndrew Boyer 
19125c896eaSAndrew Boyer 	for (i = 0; i < IOCPT_FWVERS_BUFLEN; i++)
19225c896eaSAndrew Boyer 		dev->fw_version[i] = ioread8(&dev->dev_info->fw_version[i]);
19325c896eaSAndrew Boyer 	dev->fw_version[IOCPT_FWVERS_BUFLEN - 1] = '\0';
19425c896eaSAndrew Boyer 	IOCPT_PRINT(DEBUG, "%s firmware: %s", dev->name, dev->fw_version);
19525c896eaSAndrew Boyer 
196*a677112dSAndrew Boyer 	err = iocpt_dev_identify(dev);
197*a677112dSAndrew Boyer 	if (err != 0) {
198*a677112dSAndrew Boyer 		IOCPT_PRINT(ERR, "Cannot identify device: %d, aborting",
199*a677112dSAndrew Boyer 			err);
200*a677112dSAndrew Boyer 		goto err_destroy_crypto_dev;
201*a677112dSAndrew Boyer 	}
202*a677112dSAndrew Boyer 
203*a677112dSAndrew Boyer 	err = iocpt_alloc_objs(dev);
204*a677112dSAndrew Boyer 	if (err != 0) {
205*a677112dSAndrew Boyer 		IOCPT_PRINT(ERR, "Cannot alloc device objects: %d", err);
206*a677112dSAndrew Boyer 		goto err_destroy_crypto_dev;
207*a677112dSAndrew Boyer 	}
208*a677112dSAndrew Boyer 
2094610ac93SAndrew Boyer 	err = iocpt_init(dev);
2104610ac93SAndrew Boyer 	if (err != 0) {
2114610ac93SAndrew Boyer 		IOCPT_PRINT(ERR, "Cannot init device: %d, aborting", err);
212*a677112dSAndrew Boyer 		goto err_free_objs;
2134610ac93SAndrew Boyer 	}
2144610ac93SAndrew Boyer 
2154610ac93SAndrew Boyer 	return 0;
2164610ac93SAndrew Boyer 
217*a677112dSAndrew Boyer err_free_objs:
218*a677112dSAndrew Boyer 	iocpt_free_objs(dev);
2194610ac93SAndrew Boyer err_destroy_crypto_dev:
2204610ac93SAndrew Boyer 	rte_cryptodev_pmd_destroy(cdev);
2214610ac93SAndrew Boyer err:
2224610ac93SAndrew Boyer 	return err;
2234610ac93SAndrew Boyer }
2244610ac93SAndrew Boyer 
2254610ac93SAndrew Boyer int
2264610ac93SAndrew Boyer iocpt_remove(struct rte_device *rte_dev)
2274610ac93SAndrew Boyer {
2284610ac93SAndrew Boyer 	struct rte_cryptodev *cdev;
2294610ac93SAndrew Boyer 	struct iocpt_dev *dev;
2304610ac93SAndrew Boyer 
2314610ac93SAndrew Boyer 	cdev = rte_cryptodev_pmd_get_named_dev(rte_dev->name);
2324610ac93SAndrew Boyer 	if (cdev == NULL) {
2334610ac93SAndrew Boyer 		IOCPT_PRINT(DEBUG, "Cannot find device %s", rte_dev->name);
2344610ac93SAndrew Boyer 		return -ENODEV;
2354610ac93SAndrew Boyer 	}
2364610ac93SAndrew Boyer 
2374610ac93SAndrew Boyer 	dev = cdev->data->dev_private;
2384610ac93SAndrew Boyer 
2394610ac93SAndrew Boyer 	iocpt_deinit(dev);
2404610ac93SAndrew Boyer 
241*a677112dSAndrew Boyer 	iocpt_dev_reset(dev);
242*a677112dSAndrew Boyer 
243*a677112dSAndrew Boyer 	iocpt_free_objs(dev);
244*a677112dSAndrew Boyer 
2454610ac93SAndrew Boyer 	rte_cryptodev_pmd_destroy(cdev);
2464610ac93SAndrew Boyer 
2474610ac93SAndrew Boyer 	return 0;
2484610ac93SAndrew Boyer }
2494610ac93SAndrew Boyer 
2504610ac93SAndrew Boyer RTE_LOG_REGISTER_DEFAULT(iocpt_logtype, NOTICE);
251