xref: /dpdk/drivers/common/qat/qat_device.c (revision 9e991f217fc8719e38a812dc280dba5f84db9f59)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4 
5 #include <rte_string_fns.h>
6 #include <rte_devargs.h>
7 #include <ctype.h>
8 
9 #include "qat_device.h"
10 #include "adf_transport_access_macros.h"
11 #include "qat_sym_pmd.h"
12 #include "qat_comp_pmd.h"
13 
14 /* Hardware device information per generation */
15 __extension__
16 struct qat_gen_hw_data qat_gen_config[] =  {
17 	[QAT_GEN1] = {
18 		.dev_gen = QAT_GEN1,
19 		.qp_hw_data = qat_gen1_qps,
20 		.comp_num_im_bufs_required = QAT_NUM_INTERM_BUFS_GEN1
21 	},
22 	[QAT_GEN2] = {
23 		.dev_gen = QAT_GEN2,
24 		.qp_hw_data = qat_gen1_qps,
25 		/* gen2 has same ring layout as gen1 */
26 		.comp_num_im_bufs_required = QAT_NUM_INTERM_BUFS_GEN2
27 	},
28 	[QAT_GEN3] = {
29 		.dev_gen = QAT_GEN3,
30 		.qp_hw_data = qat_gen3_qps,
31 		.comp_num_im_bufs_required = QAT_NUM_INTERM_BUFS_GEN3
32 	},
33 };
34 
35 
36 static struct qat_pci_device qat_pci_devices[RTE_PMD_QAT_MAX_PCI_DEVICES];
37 static int qat_nb_pci_devices;
38 
39 /*
40  * The set of PCI devices this driver supports
41  */
42 
43 static const struct rte_pci_id pci_id_qat_map[] = {
44 		{
45 			RTE_PCI_DEVICE(0x8086, 0x0443),
46 		},
47 		{
48 			RTE_PCI_DEVICE(0x8086, 0x37c9),
49 		},
50 		{
51 			RTE_PCI_DEVICE(0x8086, 0x19e3),
52 		},
53 		{
54 			RTE_PCI_DEVICE(0x8086, 0x6f55),
55 		},
56 		{
57 			RTE_PCI_DEVICE(0x8086, 0x18a1),
58 		},
59 		{.device_id = 0},
60 };
61 
62 static struct qat_pci_device *
63 qat_pci_get_dev(uint8_t dev_id)
64 {
65 	return &qat_pci_devices[dev_id];
66 }
67 
68 static struct qat_pci_device *
69 qat_pci_get_named_dev(const char *name)
70 {
71 	struct qat_pci_device *dev;
72 	unsigned int i;
73 
74 	if (name == NULL)
75 		return NULL;
76 
77 	for (i = 0; i < RTE_PMD_QAT_MAX_PCI_DEVICES; i++) {
78 		dev = &qat_pci_devices[i];
79 
80 		if ((dev->attached == QAT_ATTACHED) &&
81 				(strcmp(dev->name, name) == 0))
82 			return dev;
83 	}
84 
85 	return NULL;
86 }
87 
88 static uint8_t
89 qat_pci_find_free_device_index(void)
90 {
91 	uint8_t dev_id;
92 
93 	for (dev_id = 0; dev_id < RTE_PMD_QAT_MAX_PCI_DEVICES; dev_id++) {
94 		if (qat_pci_devices[dev_id].attached == QAT_DETACHED)
95 			break;
96 	}
97 	return dev_id;
98 }
99 
100 struct qat_pci_device *
101 qat_get_qat_dev_from_pci_dev(struct rte_pci_device *pci_dev)
102 {
103 	char name[QAT_DEV_NAME_MAX_LEN];
104 
105 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
106 
107 	return qat_pci_get_named_dev(name);
108 }
109 
110 static void qat_dev_parse_cmd(const char *str, struct qat_dev_cmd_param
111 		*qat_dev_cmd_param)
112 {
113 	int i = 0;
114 	const char *param;
115 
116 	while (1) {
117 		char value_str[4] = { };
118 
119 		param = qat_dev_cmd_param[i].name;
120 		if (param == NULL)
121 			return;
122 		long value = 0;
123 		const char *arg = strstr(str, param);
124 		const char *arg2 = NULL;
125 
126 		if (arg) {
127 			arg2 = arg + strlen(param);
128 			if (*arg2 != '=') {
129 				QAT_LOG(DEBUG, "parsing error '=' sign"
130 						" should immediately follow %s",
131 						param);
132 				arg2 = NULL;
133 			} else
134 				arg2++;
135 		} else {
136 			QAT_LOG(DEBUG, "%s not provided", param);
137 		}
138 		if (arg2) {
139 			int iter = 0;
140 			while (iter < 2) {
141 				if (!isdigit(*(arg2 + iter)))
142 					break;
143 				iter++;
144 			}
145 			if (!iter) {
146 				QAT_LOG(DEBUG, "parsing error %s"
147 					       " no number provided",
148 					       param);
149 			} else {
150 				memcpy(value_str, arg2, iter);
151 				value = strtol(value_str, NULL, 10);
152 				if (value > MAX_QP_THRESHOLD_SIZE) {
153 					QAT_LOG(DEBUG, "Exceeded max size of"
154 						" threshold, setting to %d",
155 						MAX_QP_THRESHOLD_SIZE);
156 					value = MAX_QP_THRESHOLD_SIZE;
157 				}
158 				QAT_LOG(DEBUG, "parsing %s = %ld",
159 						param, value);
160 			}
161 		}
162 		qat_dev_cmd_param[i].val = value;
163 		i++;
164 	}
165 }
166 
167 struct qat_pci_device *
168 qat_pci_device_allocate(struct rte_pci_device *pci_dev,
169 		struct qat_dev_cmd_param *qat_dev_cmd_param)
170 {
171 	struct qat_pci_device *qat_dev;
172 	uint8_t qat_dev_id;
173 	char name[QAT_DEV_NAME_MAX_LEN];
174 	struct rte_devargs *devargs = pci_dev->device.devargs;
175 
176 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
177 	snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
178 	if (qat_pci_get_named_dev(name) != NULL) {
179 		QAT_LOG(ERR, "QAT device with name %s already allocated!",
180 				name);
181 		return NULL;
182 	}
183 
184 	qat_dev_id = qat_pci_find_free_device_index();
185 	if (qat_dev_id == RTE_PMD_QAT_MAX_PCI_DEVICES) {
186 		QAT_LOG(ERR, "Reached maximum number of QAT devices");
187 		return NULL;
188 	}
189 
190 	qat_dev = qat_pci_get_dev(qat_dev_id);
191 	memset(qat_dev, 0, sizeof(*qat_dev));
192 	strlcpy(qat_dev->name, name, QAT_DEV_NAME_MAX_LEN);
193 	qat_dev->qat_dev_id = qat_dev_id;
194 	qat_dev->pci_dev = pci_dev;
195 	switch (qat_dev->pci_dev->id.device_id) {
196 	case 0x0443:
197 		qat_dev->qat_dev_gen = QAT_GEN1;
198 		break;
199 	case 0x37c9:
200 	case 0x19e3:
201 	case 0x6f55:
202 		qat_dev->qat_dev_gen = QAT_GEN2;
203 		break;
204 	case 0x18a1:
205 		qat_dev->qat_dev_gen = QAT_GEN3;
206 		break;
207 	default:
208 		QAT_LOG(ERR, "Invalid dev_id, can't determine generation");
209 		return NULL;
210 	}
211 
212 	if (devargs && devargs->drv_str)
213 		qat_dev_parse_cmd(devargs->drv_str, qat_dev_cmd_param);
214 
215 	rte_spinlock_init(&qat_dev->arb_csr_lock);
216 
217 	qat_dev->attached = QAT_ATTACHED;
218 
219 	qat_nb_pci_devices++;
220 
221 	QAT_LOG(DEBUG, "QAT device %d allocated, name %s, total QATs %d",
222 			qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
223 
224 	return qat_dev;
225 }
226 
227 int
228 qat_pci_device_release(struct rte_pci_device *pci_dev)
229 {
230 	struct qat_pci_device *qat_dev;
231 	char name[QAT_DEV_NAME_MAX_LEN];
232 
233 	if (pci_dev == NULL)
234 		return -EINVAL;
235 
236 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
237 	snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
238 	qat_dev = qat_pci_get_named_dev(name);
239 	if (qat_dev != NULL) {
240 
241 		/* Check that there are no service devs still on pci device */
242 		if (qat_dev->sym_dev != NULL)
243 			return -EBUSY;
244 
245 		qat_dev->attached = QAT_DETACHED;
246 		qat_nb_pci_devices--;
247 	}
248 	QAT_LOG(DEBUG, "QAT device %s released, total QATs %d",
249 				name, qat_nb_pci_devices);
250 	return 0;
251 }
252 
253 static int
254 qat_pci_dev_destroy(struct qat_pci_device *qat_pci_dev,
255 		struct rte_pci_device *pci_dev)
256 {
257 	qat_sym_dev_destroy(qat_pci_dev);
258 	qat_comp_dev_destroy(qat_pci_dev);
259 	qat_asym_dev_destroy(qat_pci_dev);
260 	return qat_pci_device_release(pci_dev);
261 }
262 
263 static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
264 		struct rte_pci_device *pci_dev)
265 {
266 	int sym_ret = 0, asym_ret = 0, comp_ret = 0;
267 	int num_pmds_created = 0;
268 	struct qat_pci_device *qat_pci_dev;
269 	struct qat_dev_cmd_param qat_dev_cmd_param[] = {
270 			{ SYM_ENQ_THRESHOLD_NAME, 0 },
271 			{ ASYM_ENQ_THRESHOLD_NAME, 0 },
272 			{ COMP_ENQ_THRESHOLD_NAME, 0 },
273 			{ NULL, 0 },
274 	};
275 
276 	QAT_LOG(DEBUG, "Found QAT device at %02x:%02x.%x",
277 			pci_dev->addr.bus,
278 			pci_dev->addr.devid,
279 			pci_dev->addr.function);
280 
281 	qat_pci_dev = qat_pci_device_allocate(pci_dev, qat_dev_cmd_param);
282 	if (qat_pci_dev == NULL)
283 		return -ENODEV;
284 
285 	sym_ret = qat_sym_dev_create(qat_pci_dev, qat_dev_cmd_param);
286 	if (sym_ret == 0) {
287 		num_pmds_created++;
288 
289 	}
290 	else
291 		QAT_LOG(WARNING,
292 				"Failed to create QAT SYM PMD on device %s",
293 				qat_pci_dev->name);
294 
295 	comp_ret = qat_comp_dev_create(qat_pci_dev, qat_dev_cmd_param);
296 	if (comp_ret == 0)
297 		num_pmds_created++;
298 	else
299 		QAT_LOG(WARNING,
300 				"Failed to create QAT COMP PMD on device %s",
301 				qat_pci_dev->name);
302 
303 	asym_ret = qat_asym_dev_create(qat_pci_dev, qat_dev_cmd_param);
304 	if (asym_ret == 0)
305 		num_pmds_created++;
306 	else
307 		QAT_LOG(WARNING,
308 				"Failed to create QAT ASYM PMD on device %s",
309 				qat_pci_dev->name);
310 
311 	if (num_pmds_created == 0)
312 		qat_pci_dev_destroy(qat_pci_dev, pci_dev);
313 
314 	return 0;
315 }
316 
317 static int qat_pci_remove(struct rte_pci_device *pci_dev)
318 {
319 	struct qat_pci_device *qat_pci_dev;
320 
321 	if (pci_dev == NULL)
322 		return -EINVAL;
323 
324 	qat_pci_dev = qat_get_qat_dev_from_pci_dev(pci_dev);
325 	if (qat_pci_dev == NULL)
326 		return 0;
327 
328 	return qat_pci_dev_destroy(qat_pci_dev, pci_dev);
329 }
330 
331 static struct rte_pci_driver rte_qat_pmd = {
332 	.id_table = pci_id_qat_map,
333 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
334 	.probe = qat_pci_probe,
335 	.remove = qat_pci_remove
336 };
337 
338 __rte_weak int
339 qat_sym_dev_create(struct qat_pci_device *qat_pci_dev __rte_unused,
340 		struct qat_dev_cmd_param *qat_dev_cmd_param __rte_unused)
341 {
342 	return 0;
343 }
344 
345 __rte_weak int
346 qat_asym_dev_create(struct qat_pci_device *qat_pci_dev __rte_unused,
347 		struct qat_dev_cmd_param *qat_dev_cmd_param __rte_unused)
348 {
349 	return 0;
350 }
351 
352 __rte_weak int
353 qat_sym_dev_destroy(struct qat_pci_device *qat_pci_dev __rte_unused)
354 {
355 	return 0;
356 }
357 
358 __rte_weak int
359 qat_asym_dev_destroy(struct qat_pci_device *qat_pci_dev __rte_unused)
360 {
361 	return 0;
362 }
363 
364 __rte_weak int
365 qat_comp_dev_create(struct qat_pci_device *qat_pci_dev __rte_unused,
366 		struct qat_dev_cmd_param *qat_dev_cmd_param __rte_unused)
367 {
368 	return 0;
369 }
370 
371 __rte_weak int
372 qat_comp_dev_destroy(struct qat_pci_device *qat_pci_dev __rte_unused)
373 {
374 	return 0;
375 }
376 
377 RTE_PMD_REGISTER_PCI(QAT_PCI_NAME, rte_qat_pmd);
378 RTE_PMD_REGISTER_PCI_TABLE(QAT_PCI_NAME, pci_id_qat_map);
379