xref: /dpdk/drivers/common/qat/qat_device.c (revision 1af60a8ce25a4a1a2ae1da6c00f432ce89a4c2eb)
198c4a35cSTomasz Jozwiak /* SPDX-License-Identifier: BSD-3-Clause
2e0a67610SKai Ji  * Copyright(c) 2018-2022 Intel Corporation
398c4a35cSTomasz Jozwiak  */
498c4a35cSTomasz Jozwiak 
590f5eedeSFiona Trahe #include <rte_string_fns.h>
647c3f7a4SArek Kusztal #include <rte_devargs.h>
747c3f7a4SArek Kusztal #include <ctype.h>
890f5eedeSFiona Trahe 
998c4a35cSTomasz Jozwiak #include "qat_device.h"
1098c4a35cSTomasz Jozwiak #include "adf_transport_access_macros.h"
11e0a67610SKai Ji #include "qat_sym.h"
12a124830aSFiona Trahe #include "qat_comp_pmd.h"
13b17d16fbSArek Kusztal #include "adf_pf2vf_msg.h"
14c546d6e3SArek Kusztal #include "qat_pf2vf.h"
15b17d16fbSArek Kusztal 
167b1374b1SArkadiusz Kusztal #define NOT_NULL(arg, func, msg, ...)		\
177b1374b1SArkadiusz Kusztal 	do {					\
187b1374b1SArkadiusz Kusztal 		if (arg == NULL) {		\
197b1374b1SArkadiusz Kusztal 			QAT_LOG(ERR,		\
207b1374b1SArkadiusz Kusztal 			msg, ##__VA_ARGS__);	\
217b1374b1SArkadiusz Kusztal 			func;			\
227b1374b1SArkadiusz Kusztal 		}				\
237b1374b1SArkadiusz Kusztal 	} while (0)
247b1374b1SArkadiusz Kusztal 
2504dd78d1SFan Zhang /* Hardware device information per generation */
2604dd78d1SFan Zhang struct qat_gen_hw_data qat_gen_config[QAT_N_GENS];
2704dd78d1SFan Zhang struct qat_dev_hw_spec_funcs *qat_dev_hw_spec[QAT_N_GENS];
2804dd78d1SFan Zhang 
29477d7d05SArkadiusz Kusztal struct qat_service qat_service[QAT_MAX_SERVICES];
30477d7d05SArkadiusz Kusztal 
319904ff68SArek Kusztal /* per-process array of device data */
329904ff68SArek Kusztal struct qat_device_info qat_pci_devs[RTE_PMD_QAT_MAX_PCI_DEVICES];
3398c4a35cSTomasz Jozwiak static int qat_nb_pci_devices;
3498c4a35cSTomasz Jozwiak 
3598c4a35cSTomasz Jozwiak /*
3698c4a35cSTomasz Jozwiak  * The set of PCI devices this driver supports
3798c4a35cSTomasz Jozwiak  */
3898c4a35cSTomasz Jozwiak 
3998c4a35cSTomasz Jozwiak static const struct rte_pci_id pci_id_qat_map[] = {
4098c4a35cSTomasz Jozwiak 		{
4198c4a35cSTomasz Jozwiak 			RTE_PCI_DEVICE(0x8086, 0x0443),
4298c4a35cSTomasz Jozwiak 		},
4398c4a35cSTomasz Jozwiak 		{
4498c4a35cSTomasz Jozwiak 			RTE_PCI_DEVICE(0x8086, 0x37c9),
4598c4a35cSTomasz Jozwiak 		},
4698c4a35cSTomasz Jozwiak 		{
4798c4a35cSTomasz Jozwiak 			RTE_PCI_DEVICE(0x8086, 0x19e3),
4898c4a35cSTomasz Jozwiak 		},
4998c4a35cSTomasz Jozwiak 		{
5098c4a35cSTomasz Jozwiak 			RTE_PCI_DEVICE(0x8086, 0x6f55),
5198c4a35cSTomasz Jozwiak 		},
521f5e4053SFiona Trahe 		{
537b08003bSAdam Dybkowski 			RTE_PCI_DEVICE(0x8086, 0x18ef),
547b08003bSAdam Dybkowski 		},
557b08003bSAdam Dybkowski 		{
561f5e4053SFiona Trahe 			RTE_PCI_DEVICE(0x8086, 0x18a1),
571f5e4053SFiona Trahe 		},
588f393c4fSArek Kusztal 		{
59f925068aSCiara Power 			RTE_PCI_DEVICE(0x8086, 0x578b),
60f925068aSCiara Power 		},
61f925068aSCiara Power 		{
628f393c4fSArek Kusztal 			RTE_PCI_DEVICE(0x8086, 0x4941),
638f393c4fSArek Kusztal 		},
64f4eac3a0SArek Kusztal 		{
65f4eac3a0SArek Kusztal 			RTE_PCI_DEVICE(0x8086, 0x4943),
66f4eac3a0SArek Kusztal 		},
674728d843SCiara Power 		{
684728d843SCiara Power 			RTE_PCI_DEVICE(0x8086, 0x4945),
694728d843SCiara Power 		},
7059cda512SCiara Power 		{
7159cda512SCiara Power 			RTE_PCI_DEVICE(0x8086, 0x4947),
7259cda512SCiara Power 		},
73e9271821SNishikant Nayak 		{
74e9271821SNishikant Nayak 			RTE_PCI_DEVICE(0x8086, 0x1454),
75e9271821SNishikant Nayak 		},
762e98e808SArkadiusz Kusztal 		{
772e98e808SArkadiusz Kusztal 			RTE_PCI_DEVICE(0x8086, 0x0da5),
782e98e808SArkadiusz Kusztal 		},
7998c4a35cSTomasz Jozwiak 		{.device_id = 0},
8098c4a35cSTomasz Jozwiak };
8198c4a35cSTomasz Jozwiak 
825438e4ecSFan Zhang static int
835438e4ecSFan Zhang qat_pci_get_extra_size(enum qat_device_gen qat_dev_gen)
845438e4ecSFan Zhang {
855438e4ecSFan Zhang 	struct qat_dev_hw_spec_funcs *ops_hw =
865438e4ecSFan Zhang 		qat_dev_hw_spec[qat_dev_gen];
878f1d23ecSDavid Marchand 	if (ops_hw->qat_dev_get_extra_size == NULL)
888f1d23ecSDavid Marchand 		return -ENOTSUP;
895438e4ecSFan Zhang 	return ops_hw->qat_dev_get_extra_size();
905438e4ecSFan Zhang }
915438e4ecSFan Zhang 
9298c4a35cSTomasz Jozwiak static struct qat_pci_device *
9398c4a35cSTomasz Jozwiak qat_pci_get_named_dev(const char *name)
9498c4a35cSTomasz Jozwiak {
9598c4a35cSTomasz Jozwiak 	unsigned int i;
9698c4a35cSTomasz Jozwiak 
9798c4a35cSTomasz Jozwiak 	if (name == NULL)
9898c4a35cSTomasz Jozwiak 		return NULL;
9998c4a35cSTomasz Jozwiak 
10098c4a35cSTomasz Jozwiak 	for (i = 0; i < RTE_PMD_QAT_MAX_PCI_DEVICES; i++) {
1019904ff68SArek Kusztal 		if (qat_pci_devs[i].mz &&
1029904ff68SArek Kusztal 				(strcmp(((struct qat_pci_device *)
1039904ff68SArek Kusztal 				qat_pci_devs[i].mz->addr)->name, name)
1049904ff68SArek Kusztal 				== 0))
1059904ff68SArek Kusztal 			return (struct qat_pci_device *)
1069904ff68SArek Kusztal 				qat_pci_devs[i].mz->addr;
10798c4a35cSTomasz Jozwiak 	}
10898c4a35cSTomasz Jozwiak 
10998c4a35cSTomasz Jozwiak 	return NULL;
11098c4a35cSTomasz Jozwiak }
11198c4a35cSTomasz Jozwiak 
11298c4a35cSTomasz Jozwiak static uint8_t
11398c4a35cSTomasz Jozwiak qat_pci_find_free_device_index(void)
11498c4a35cSTomasz Jozwiak {
11598c4a35cSTomasz Jozwiak 		uint8_t dev_id;
11698c4a35cSTomasz Jozwiak 
1179904ff68SArek Kusztal 		for (dev_id = 0; dev_id < RTE_PMD_QAT_MAX_PCI_DEVICES;
1189904ff68SArek Kusztal 				dev_id++) {
1199904ff68SArek Kusztal 			if (qat_pci_devs[dev_id].mz == NULL)
12098c4a35cSTomasz Jozwiak 				break;
12198c4a35cSTomasz Jozwiak 		}
12298c4a35cSTomasz Jozwiak 		return dev_id;
12398c4a35cSTomasz Jozwiak }
12498c4a35cSTomasz Jozwiak 
125477d7d05SArkadiusz Kusztal static struct qat_pci_device *
12698c4a35cSTomasz Jozwiak qat_get_qat_dev_from_pci_dev(struct rte_pci_device *pci_dev)
12798c4a35cSTomasz Jozwiak {
12898c4a35cSTomasz Jozwiak 	char name[QAT_DEV_NAME_MAX_LEN];
12998c4a35cSTomasz Jozwiak 
13098c4a35cSTomasz Jozwiak 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
13198c4a35cSTomasz Jozwiak 
13298c4a35cSTomasz Jozwiak 	return qat_pci_get_named_dev(name);
13398c4a35cSTomasz Jozwiak }
13498c4a35cSTomasz Jozwiak 
1357b1374b1SArkadiusz Kusztal static enum qat_device_gen
1367b1374b1SArkadiusz Kusztal pick_gen(const struct rte_pci_device *pci_dev)
1377b1374b1SArkadiusz Kusztal {
1387b1374b1SArkadiusz Kusztal 	switch (pci_dev->id.device_id) {
1397b1374b1SArkadiusz Kusztal 	case 0x0443:
1407b1374b1SArkadiusz Kusztal 		return QAT_GEN1;
1417b1374b1SArkadiusz Kusztal 	case 0x37c9:
1427b1374b1SArkadiusz Kusztal 	case 0x19e3:
1437b1374b1SArkadiusz Kusztal 	case 0x6f55:
1447b1374b1SArkadiusz Kusztal 	case 0x18ef:
1457b1374b1SArkadiusz Kusztal 		return QAT_GEN2;
1467b1374b1SArkadiusz Kusztal 	case 0x18a1:
147f925068aSCiara Power 	case 0x578b:
1487b1374b1SArkadiusz Kusztal 		return QAT_GEN3;
1497b1374b1SArkadiusz Kusztal 	case 0x4941:
1507b1374b1SArkadiusz Kusztal 	case 0x4943:
1517b1374b1SArkadiusz Kusztal 	case 0x4945:
1527b1374b1SArkadiusz Kusztal 		return QAT_GEN4;
15359cda512SCiara Power 	case 0x4947:
15459cda512SCiara Power 		return QAT_GEN5;
155e9271821SNishikant Nayak 	case 0x1454:
156e9271821SNishikant Nayak 		return QAT_GEN_LCE;
1572e98e808SArkadiusz Kusztal 	case 0x0da5:
1582e98e808SArkadiusz Kusztal 		return QAT_VQAT;
1597b1374b1SArkadiusz Kusztal 	default:
1607b1374b1SArkadiusz Kusztal 		QAT_LOG(ERR, "Invalid dev_id, can't determine generation");
1617b1374b1SArkadiusz Kusztal 		return QAT_N_GENS;
1627b1374b1SArkadiusz Kusztal 	}
1637b1374b1SArkadiusz Kusztal }
1647b1374b1SArkadiusz Kusztal 
165f925068aSCiara Power static int
166f925068aSCiara Power wireless_slice_support(uint16_t pci_dev_id)
167f925068aSCiara Power {
16859cda512SCiara Power 	return pci_dev_id == 0x578b ||
16959cda512SCiara Power 			pci_dev_id == 0x4947;
170f925068aSCiara Power }
171f925068aSCiara Power 
17299ab2806SArkadiusz Kusztal /* This function base on the atoi function peculiarity, non integral part
17399ab2806SArkadiusz Kusztal  * other than the equals sign is ignored. It will not work with other conversion
17499ab2806SArkadiusz Kusztal  * functions like strt*.
17599ab2806SArkadiusz Kusztal  */
17699ab2806SArkadiusz Kusztal char *qat_dev_cmdline_get_val(struct qat_pci_device *qat_dev,
17799ab2806SArkadiusz Kusztal 	const char *key)
17899ab2806SArkadiusz Kusztal {
17999ab2806SArkadiusz Kusztal 	if (qat_dev->command_line == NULL)
18099ab2806SArkadiusz Kusztal 		return NULL;
18199ab2806SArkadiusz Kusztal 	key = strstr(qat_dev->command_line, key);
18299ab2806SArkadiusz Kusztal 	/* At this point, a key should be validated */
18399ab2806SArkadiusz Kusztal 	return key ? strchr(key, '=') + 1 : NULL;
18499ab2806SArkadiusz Kusztal }
18599ab2806SArkadiusz Kusztal 
18699ab2806SArkadiusz Kusztal static int cmdline_validate(const char *arg)
18799ab2806SArkadiusz Kusztal {
18899ab2806SArkadiusz Kusztal 	int i, len;
18999ab2806SArkadiusz Kusztal 	char *eq_sign = strchr(arg, '=');
19099ab2806SArkadiusz Kusztal 	/* Check for the equal sign */
19199ab2806SArkadiusz Kusztal 	if (eq_sign == NULL) {
19299ab2806SArkadiusz Kusztal 		QAT_LOG(ERR, "malformed string, no equals sign, %s", arg);
19399ab2806SArkadiusz Kusztal 		return 0;
19499ab2806SArkadiusz Kusztal 	}
19599ab2806SArkadiusz Kusztal 	/* Check if an argument is not empty */
19699ab2806SArkadiusz Kusztal 	len = strlen(eq_sign) - 1;
19799ab2806SArkadiusz Kusztal 	if (len == 0) {
19899ab2806SArkadiusz Kusztal 		QAT_LOG(ERR, "malformed string, empty argument, %s", arg);
19999ab2806SArkadiusz Kusztal 		return 0;
20099ab2806SArkadiusz Kusztal 	}
20199ab2806SArkadiusz Kusztal 	len = eq_sign - arg;
20299ab2806SArkadiusz Kusztal 	for (i = 0; i < QAT_MAX_SERVICES + 1; i++) {
20399ab2806SArkadiusz Kusztal 		int j = 0;
20499ab2806SArkadiusz Kusztal 		const char *def = NULL;
20599ab2806SArkadiusz Kusztal 
20699ab2806SArkadiusz Kusztal 		if (!qat_cmdline_defines[i])
20799ab2806SArkadiusz Kusztal 			continue;
20899ab2806SArkadiusz Kusztal 		while ((def = qat_cmdline_defines[i][j++])) {
20999ab2806SArkadiusz Kusztal 			if (strncmp(def, arg, len))
21099ab2806SArkadiusz Kusztal 				continue;
21199ab2806SArkadiusz Kusztal 			QAT_LOG(DEBUG, "Found %s command line argument",
21299ab2806SArkadiusz Kusztal 				def);
21399ab2806SArkadiusz Kusztal 			return 1;
21499ab2806SArkadiusz Kusztal 		}
21599ab2806SArkadiusz Kusztal 	}
21699ab2806SArkadiusz Kusztal 	return 0;
21799ab2806SArkadiusz Kusztal }
21899ab2806SArkadiusz Kusztal 
21999ab2806SArkadiusz Kusztal static int
22099ab2806SArkadiusz Kusztal qat_dev_parse_command_line(struct qat_pci_device *qat_dev,
22199ab2806SArkadiusz Kusztal 	struct rte_devargs *devargs)
22299ab2806SArkadiusz Kusztal {
22399ab2806SArkadiusz Kusztal 	int len = 0;
22499ab2806SArkadiusz Kusztal 	char *token = NULL;
22599ab2806SArkadiusz Kusztal 
22699ab2806SArkadiusz Kusztal 	if (!devargs)
22799ab2806SArkadiusz Kusztal 		return 0;
22899ab2806SArkadiusz Kusztal 
22999ab2806SArkadiusz Kusztal 	len = strlen(devargs->drv_str);
23099ab2806SArkadiusz Kusztal 	if (len == 0)
23199ab2806SArkadiusz Kusztal 		return 0;
23299ab2806SArkadiusz Kusztal 	/* Allocate per-device command line */
23399ab2806SArkadiusz Kusztal 	qat_dev->command_line = rte_malloc(NULL, len, 0);
23499ab2806SArkadiusz Kusztal 	if (qat_dev->command_line == NULL) {
23599ab2806SArkadiusz Kusztal 		QAT_LOG(ERR, "Cannot allocate memory for command line");
23699ab2806SArkadiusz Kusztal 		return -1;
23799ab2806SArkadiusz Kusztal 	}
23899ab2806SArkadiusz Kusztal 	strcpy(qat_dev->command_line, devargs->drv_str);
23999ab2806SArkadiusz Kusztal 	token = strtok(qat_dev->command_line, ",");
24099ab2806SArkadiusz Kusztal 	while (token != NULL) {
24199ab2806SArkadiusz Kusztal 		if (!cmdline_validate(token)) {
24299ab2806SArkadiusz Kusztal 			QAT_LOG(ERR, "Incorrect command line argument: %s",
24399ab2806SArkadiusz Kusztal 				token);
24499ab2806SArkadiusz Kusztal 			return -1;
24599ab2806SArkadiusz Kusztal 		}
24699ab2806SArkadiusz Kusztal 		token = strtok(NULL, ",");
24799ab2806SArkadiusz Kusztal 	}
24899ab2806SArkadiusz Kusztal 	/* Copy once againe the entire string, strtok already altered the contents */
24999ab2806SArkadiusz Kusztal 	strcpy(qat_dev->command_line, devargs->drv_str);
25099ab2806SArkadiusz Kusztal 	return 0;
25199ab2806SArkadiusz Kusztal }
25299ab2806SArkadiusz Kusztal 
25399ab2806SArkadiusz Kusztal static struct qat_pci_device *
25499ab2806SArkadiusz Kusztal qat_pci_device_allocate(struct rte_pci_device *pci_dev)
25598c4a35cSTomasz Jozwiak {
25698c4a35cSTomasz Jozwiak 	struct qat_pci_device *qat_dev;
2575438e4ecSFan Zhang 	enum qat_device_gen qat_dev_gen;
2589904ff68SArek Kusztal 	uint8_t qat_dev_id = 0;
25998c4a35cSTomasz Jozwiak 	char name[QAT_DEV_NAME_MAX_LEN];
26047c3f7a4SArek Kusztal 	struct rte_devargs *devargs = pci_dev->device.devargs;
2615438e4ecSFan Zhang 	struct qat_dev_hw_spec_funcs *ops_hw;
2625438e4ecSFan Zhang 	struct rte_mem_resource *mem_resource;
2635438e4ecSFan Zhang 	const struct rte_memzone *qat_dev_mz;
2645438e4ecSFan Zhang 	int qat_dev_size, extra_size;
26599ab2806SArkadiusz Kusztal 	char *cmdline = NULL;
26698c4a35cSTomasz Jozwiak 
26798c4a35cSTomasz Jozwiak 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
26898c4a35cSTomasz Jozwiak 	snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
2699904ff68SArek Kusztal 
2707b1374b1SArkadiusz Kusztal 	qat_dev_gen = pick_gen(pci_dev);
2717b1374b1SArkadiusz Kusztal 	if (qat_dev_gen == QAT_N_GENS) {
2725438e4ecSFan Zhang 		QAT_LOG(ERR, "Invalid dev_id, can't determine generation");
2735438e4ecSFan Zhang 		return NULL;
2745438e4ecSFan Zhang 	}
2755438e4ecSFan Zhang 
2769904ff68SArek Kusztal 	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
2779904ff68SArek Kusztal 		const struct rte_memzone *mz = rte_memzone_lookup(name);
2789904ff68SArek Kusztal 
2799904ff68SArek Kusztal 		if (mz == NULL) {
2809904ff68SArek Kusztal 			QAT_LOG(ERR,
2819904ff68SArek Kusztal 				"Secondary can't find %s mz, did primary create device?",
2829904ff68SArek Kusztal 				name);
2839904ff68SArek Kusztal 			return NULL;
2849904ff68SArek Kusztal 		}
2859904ff68SArek Kusztal 		qat_dev = mz->addr;
2869904ff68SArek Kusztal 		qat_pci_devs[qat_dev->qat_dev_id].mz = mz;
2879904ff68SArek Kusztal 		qat_pci_devs[qat_dev->qat_dev_id].pci_dev = pci_dev;
2889904ff68SArek Kusztal 		qat_nb_pci_devices++;
2899904ff68SArek Kusztal 		QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
2909904ff68SArek Kusztal 			qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
2919904ff68SArek Kusztal 		return qat_dev;
2929904ff68SArek Kusztal 	}
2939904ff68SArek Kusztal 
29498c4a35cSTomasz Jozwiak 	if (qat_pci_get_named_dev(name) != NULL) {
29598c4a35cSTomasz Jozwiak 		QAT_LOG(ERR, "QAT device with name %s already allocated!",
29698c4a35cSTomasz Jozwiak 				name);
29798c4a35cSTomasz Jozwiak 		return NULL;
29898c4a35cSTomasz Jozwiak 	}
29998c4a35cSTomasz Jozwiak 
30098c4a35cSTomasz Jozwiak 	qat_dev_id = qat_pci_find_free_device_index();
30198c4a35cSTomasz Jozwiak 	if (qat_dev_id == RTE_PMD_QAT_MAX_PCI_DEVICES) {
30298c4a35cSTomasz Jozwiak 		QAT_LOG(ERR, "Reached maximum number of QAT devices");
30398c4a35cSTomasz Jozwiak 		return NULL;
30498c4a35cSTomasz Jozwiak 	}
30598c4a35cSTomasz Jozwiak 
3065438e4ecSFan Zhang 	extra_size = qat_pci_get_extra_size(qat_dev_gen);
3075438e4ecSFan Zhang 	if (extra_size < 0) {
3085438e4ecSFan Zhang 		QAT_LOG(ERR, "QAT internal error: no pci pointer for gen %d",
3095438e4ecSFan Zhang 			qat_dev_gen);
3105438e4ecSFan Zhang 		return NULL;
3115438e4ecSFan Zhang 	}
3125438e4ecSFan Zhang 
313477d7d05SArkadiusz Kusztal 	qat_dev_size = sizeof(struct qat_pci_device) + sizeof(void *) *
314477d7d05SArkadiusz Kusztal 				QAT_MAX_SERVICES + extra_size;
3155438e4ecSFan Zhang 	qat_dev_mz = rte_memzone_reserve(name, qat_dev_size,
3169904ff68SArek Kusztal 		rte_socket_id(), 0);
3179904ff68SArek Kusztal 
3185438e4ecSFan Zhang 	if (qat_dev_mz == NULL) {
3199904ff68SArek Kusztal 		QAT_LOG(ERR, "Error when allocating memzone for QAT_%d",
3209904ff68SArek Kusztal 			qat_dev_id);
3219904ff68SArek Kusztal 		return NULL;
3229904ff68SArek Kusztal 	}
3239904ff68SArek Kusztal 
3245438e4ecSFan Zhang 	qat_dev = qat_dev_mz->addr;
3255438e4ecSFan Zhang 	memset(qat_dev, 0, qat_dev_size);
3265438e4ecSFan Zhang 	qat_dev->dev_private = qat_dev + 1;
32790f5eedeSFiona Trahe 	strlcpy(qat_dev->name, name, QAT_DEV_NAME_MAX_LEN);
32898c4a35cSTomasz Jozwiak 	qat_dev->qat_dev_id = qat_dev_id;
3295438e4ecSFan Zhang 	qat_dev->qat_dev_gen = qat_dev_gen;
3302e98e808SArkadiusz Kusztal 	qat_pci_devs[qat_dev_id].pci_dev = pci_dev;
33198c4a35cSTomasz Jozwiak 
332f925068aSCiara Power 	if (wireless_slice_support(pci_dev->id.device_id))
333b7bd72d8SArkadiusz Kusztal 		qat_dev->options.has_wireless_slice = 1;
334f925068aSCiara Power 
3355438e4ecSFan Zhang 	ops_hw = qat_dev_hw_spec[qat_dev->qat_dev_gen];
3367b1374b1SArkadiusz Kusztal 	NOT_NULL(ops_hw->qat_dev_get_misc_bar, goto error,
3377b1374b1SArkadiusz Kusztal 		"QAT internal error! qat_dev_get_misc_bar function not set");
3385438e4ecSFan Zhang 	if (ops_hw->qat_dev_get_misc_bar(&mem_resource, pci_dev) == 0) {
3395438e4ecSFan Zhang 		if (mem_resource->addr == NULL) {
3405438e4ecSFan Zhang 			QAT_LOG(ERR, "QAT cannot get access to VF misc bar");
3417b1374b1SArkadiusz Kusztal 			goto error;
342b17d16fbSArek Kusztal 		}
3435438e4ecSFan Zhang 		qat_dev->misc_bar_io_addr = mem_resource->addr;
3445438e4ecSFan Zhang 	} else
3455438e4ecSFan Zhang 		qat_dev->misc_bar_io_addr = NULL;
346b17d16fbSArek Kusztal 
34799ab2806SArkadiusz Kusztal 	/* Parse the command line */
34899ab2806SArkadiusz Kusztal 	if (qat_dev_parse_command_line(qat_dev, devargs))
34999ab2806SArkadiusz Kusztal 		goto error;
35099ab2806SArkadiusz Kusztal 
35199ab2806SArkadiusz Kusztal 	/* Parse the arguments */
35299ab2806SArkadiusz Kusztal 	cmdline = qat_dev_cmdline_get_val(qat_dev, QAT_LEGACY_CAPA);
35399ab2806SArkadiusz Kusztal 	if (cmdline)
354b7bd72d8SArkadiusz Kusztal 		qat_dev->options.legacy_alg = atoi(cmdline);
35547c3f7a4SArek Kusztal 
356960ff4d6SArek Kusztal 	if (qat_read_qp_config(qat_dev)) {
3578f393c4fSArek Kusztal 		QAT_LOG(ERR,
3588f393c4fSArek Kusztal 			"Cannot acquire ring configuration for QAT_%d",
3598f393c4fSArek Kusztal 			qat_dev_id);
3607b1374b1SArkadiusz Kusztal 		goto error;
3618f393c4fSArek Kusztal 	}
3627b1374b1SArkadiusz Kusztal 	NOT_NULL(ops_hw->qat_dev_reset_ring_pairs, goto error,
3637b1374b1SArkadiusz Kusztal 		"QAT internal error! Reset ring pairs function not set, gen : %d",
3647b1374b1SArkadiusz Kusztal 		qat_dev_gen);
3657b1374b1SArkadiusz Kusztal 	if (ops_hw->qat_dev_reset_ring_pairs(qat_dev)) {
3667b1374b1SArkadiusz Kusztal 		QAT_LOG(ERR,
3677b1374b1SArkadiusz Kusztal 			"Cannot reset ring pairs, does pf driver supports pf2vf comms?"
3687b1374b1SArkadiusz Kusztal 			);
3697b1374b1SArkadiusz Kusztal 		goto error;
3707b1374b1SArkadiusz Kusztal 	}
3717b1374b1SArkadiusz Kusztal 	NOT_NULL(ops_hw->qat_dev_get_slice_map, goto error,
3727b1374b1SArkadiusz Kusztal 		"QAT internal error! Read slice function not set, gen : %d",
3737b1374b1SArkadiusz Kusztal 		qat_dev_gen);
374b7bd72d8SArkadiusz Kusztal 	if (ops_hw->qat_dev_get_slice_map(&qat_dev->options.slice_map, pci_dev) < 0) {
37530d38a71SDavid Marchand 		QAT_LOG(ERR,
37630d38a71SDavid Marchand 			"Cannot read slice configuration");
3777b1374b1SArkadiusz Kusztal 		goto error;
3787b1374b1SArkadiusz Kusztal 	}
3797b1374b1SArkadiusz Kusztal 	rte_spinlock_init(&qat_dev->arb_csr_lock);
3805438e4ecSFan Zhang 
3815438e4ecSFan Zhang 	/* No errors when allocating, attach memzone with
3825438e4ecSFan Zhang 	 * qat_dev to list of devices
3835438e4ecSFan Zhang 	 */
3845438e4ecSFan Zhang 	qat_pci_devs[qat_dev_id].mz = qat_dev_mz;
38598c4a35cSTomasz Jozwiak 	qat_nb_pci_devices++;
38698c4a35cSTomasz Jozwiak 
3879904ff68SArek Kusztal 	QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
38898c4a35cSTomasz Jozwiak 			qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
38998c4a35cSTomasz Jozwiak 
39098c4a35cSTomasz Jozwiak 	return qat_dev;
3917b1374b1SArkadiusz Kusztal error:
39299ab2806SArkadiusz Kusztal 	rte_free(qat_dev->command_line);
393*1af60a8cSStephen Hemminger 	rte_memzone_free(qat_dev_mz);
3947b1374b1SArkadiusz Kusztal 	return NULL;
39598c4a35cSTomasz Jozwiak }
39698c4a35cSTomasz Jozwiak 
3979904ff68SArek Kusztal static int
39898c4a35cSTomasz Jozwiak qat_pci_device_release(struct rte_pci_device *pci_dev)
39998c4a35cSTomasz Jozwiak {
40098c4a35cSTomasz Jozwiak 	struct qat_pci_device *qat_dev;
40198c4a35cSTomasz Jozwiak 	char name[QAT_DEV_NAME_MAX_LEN];
402477d7d05SArkadiusz Kusztal 	int busy = 0, i;
40398c4a35cSTomasz Jozwiak 
40498c4a35cSTomasz Jozwiak 	if (pci_dev == NULL)
40598c4a35cSTomasz Jozwiak 		return -EINVAL;
40698c4a35cSTomasz Jozwiak 
40798c4a35cSTomasz Jozwiak 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
40898c4a35cSTomasz Jozwiak 	snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
40998c4a35cSTomasz Jozwiak 	qat_dev = qat_pci_get_named_dev(name);
41098c4a35cSTomasz Jozwiak 	if (qat_dev != NULL) {
41198c4a35cSTomasz Jozwiak 
4129904ff68SArek Kusztal 		struct qat_device_info *inst =
4139904ff68SArek Kusztal 				&qat_pci_devs[qat_dev->qat_dev_id];
41498c4a35cSTomasz Jozwiak 		/* Check that there are no service devs still on pci device */
41598c4a35cSTomasz Jozwiak 
4169904ff68SArek Kusztal 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
417477d7d05SArkadiusz Kusztal 			for (i = 0; i < QAT_MAX_SERVICES; i++) {
418d77817d0SArkadiusz Kusztal 				if (qat_dev->pmd[i] != NULL) {
419477d7d05SArkadiusz Kusztal 					QAT_LOG(DEBUG, "QAT %s device %s is busy",
420477d7d05SArkadiusz Kusztal 						qat_service[i].name, name);
4219904ff68SArek Kusztal 					busy = 1;
422d77817d0SArkadiusz Kusztal 				}
423d77817d0SArkadiusz Kusztal 			}
4249904ff68SArek Kusztal 			if (busy)
4259904ff68SArek Kusztal 				return -EBUSY;
4269904ff68SArek Kusztal 			rte_memzone_free(inst->mz);
4279904ff68SArek Kusztal 		}
4289904ff68SArek Kusztal 		memset(inst, 0, sizeof(struct qat_device_info));
4299904ff68SArek Kusztal 		qat_nb_pci_devices--;
43098c4a35cSTomasz Jozwiak 		QAT_LOG(DEBUG, "QAT device %s released, total QATs %d",
43198c4a35cSTomasz Jozwiak 					name, qat_nb_pci_devices);
4329904ff68SArek Kusztal 	}
43398c4a35cSTomasz Jozwiak 	return 0;
43498c4a35cSTomasz Jozwiak }
43598c4a35cSTomasz Jozwiak 
43698c4a35cSTomasz Jozwiak static int
43798c4a35cSTomasz Jozwiak qat_pci_dev_destroy(struct qat_pci_device *qat_pci_dev,
43898c4a35cSTomasz Jozwiak 		struct rte_pci_device *pci_dev)
43998c4a35cSTomasz Jozwiak {
440477d7d05SArkadiusz Kusztal 	int i;
441477d7d05SArkadiusz Kusztal 
442477d7d05SArkadiusz Kusztal 	for (i = 0; i < QAT_MAX_SERVICES; i++) {
443d77817d0SArkadiusz Kusztal 		if (!qat_service[i].dev_destroy)
444477d7d05SArkadiusz Kusztal 			continue;
445477d7d05SArkadiusz Kusztal 		qat_service[i].dev_destroy(qat_pci_dev);
446477d7d05SArkadiusz Kusztal 	}
44798c4a35cSTomasz Jozwiak 	return qat_pci_device_release(pci_dev);
44898c4a35cSTomasz Jozwiak }
44998c4a35cSTomasz Jozwiak 
45098c4a35cSTomasz Jozwiak static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
45198c4a35cSTomasz Jozwiak 		struct rte_pci_device *pci_dev)
45298c4a35cSTomasz Jozwiak {
453477d7d05SArkadiusz Kusztal 	int i, ret = 0, num_pmds_created = 0;
45498c4a35cSTomasz Jozwiak 	struct qat_pci_device *qat_pci_dev;
45598c4a35cSTomasz Jozwiak 
45698c4a35cSTomasz Jozwiak 	QAT_LOG(DEBUG, "Found QAT device at %02x:%02x.%x",
45798c4a35cSTomasz Jozwiak 			pci_dev->addr.bus,
45898c4a35cSTomasz Jozwiak 			pci_dev->addr.devid,
45998c4a35cSTomasz Jozwiak 			pci_dev->addr.function);
46098c4a35cSTomasz Jozwiak 
46199ab2806SArkadiusz Kusztal 	qat_pci_dev = qat_pci_device_allocate(pci_dev);
46298c4a35cSTomasz Jozwiak 	if (qat_pci_dev == NULL)
46398c4a35cSTomasz Jozwiak 		return -ENODEV;
46498c4a35cSTomasz Jozwiak 
465477d7d05SArkadiusz Kusztal 	for (i = 0; i < QAT_MAX_SERVICES; i++) {
466477d7d05SArkadiusz Kusztal 		if (!qat_service[i].dev_create)
467477d7d05SArkadiusz Kusztal 			continue;
468477d7d05SArkadiusz Kusztal 		ret = qat_service[i].dev_create(qat_pci_dev);
469477d7d05SArkadiusz Kusztal 		if (ret == 0)
4708451f04dSFiona Trahe 			num_pmds_created++;
471477d7d05SArkadiusz Kusztal 		else {
472477d7d05SArkadiusz Kusztal 			QAT_LOG(WARNING, "Failed to create %s PMD on device %s",
473477d7d05SArkadiusz Kusztal 				qat_service[i].name,
474477d7d05SArkadiusz Kusztal 				qat_pci_dev->name);
47547c3f7a4SArek Kusztal 		}
476477d7d05SArkadiusz Kusztal 	}
4778451f04dSFiona Trahe 
4788451f04dSFiona Trahe 	if (num_pmds_created == 0)
4798451f04dSFiona Trahe 		qat_pci_dev_destroy(qat_pci_dev, pci_dev);
48098c4a35cSTomasz Jozwiak 
48198c4a35cSTomasz Jozwiak 	return 0;
48298c4a35cSTomasz Jozwiak }
48398c4a35cSTomasz Jozwiak 
4845438e4ecSFan Zhang static int
4855438e4ecSFan Zhang qat_pci_remove(struct rte_pci_device *pci_dev)
48698c4a35cSTomasz Jozwiak {
48798c4a35cSTomasz Jozwiak 	struct qat_pci_device *qat_pci_dev;
48898c4a35cSTomasz Jozwiak 
48998c4a35cSTomasz Jozwiak 	if (pci_dev == NULL)
49098c4a35cSTomasz Jozwiak 		return -EINVAL;
49198c4a35cSTomasz Jozwiak 
49298c4a35cSTomasz Jozwiak 	qat_pci_dev = qat_get_qat_dev_from_pci_dev(pci_dev);
49398c4a35cSTomasz Jozwiak 	if (qat_pci_dev == NULL)
49498c4a35cSTomasz Jozwiak 		return 0;
49598c4a35cSTomasz Jozwiak 
49698c4a35cSTomasz Jozwiak 	return qat_pci_dev_destroy(qat_pci_dev, pci_dev);
49798c4a35cSTomasz Jozwiak }
49898c4a35cSTomasz Jozwiak 
49998c4a35cSTomasz Jozwiak static struct rte_pci_driver rte_qat_pmd = {
50098c4a35cSTomasz Jozwiak 	.id_table = pci_id_qat_map,
50198c4a35cSTomasz Jozwiak 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
50298c4a35cSTomasz Jozwiak 	.probe = qat_pci_probe,
50398c4a35cSTomasz Jozwiak 	.remove = qat_pci_remove
50498c4a35cSTomasz Jozwiak };
50598c4a35cSTomasz Jozwiak 
50698c4a35cSTomasz Jozwiak RTE_PMD_REGISTER_PCI(QAT_PCI_NAME, rte_qat_pmd);
50798c4a35cSTomasz Jozwiak RTE_PMD_REGISTER_PCI_TABLE(QAT_PCI_NAME, pci_id_qat_map);
508a0fe0cc5SDidier Pallard RTE_PMD_REGISTER_KMOD_DEP(QAT_PCI_NAME, "* igb_uio | uio_pci_generic | vfio-pci");
509