Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018-2022 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.h"
12 : : #include "qat_comp_pmd.h"
13 : : #include "adf_pf2vf_msg.h"
14 : : #include "qat_pf2vf.h"
15 : :
16 : : #define NOT_NULL(arg, func, msg, ...) \
17 : : do { \
18 : : if (arg == NULL) { \
19 : : QAT_LOG(ERR, \
20 : : msg, ##__VA_ARGS__); \
21 : : func; \
22 : : } \
23 : : } while (0)
24 : :
25 : : /* Hardware device information per generation */
26 : : struct qat_gen_hw_data qat_gen_config[QAT_N_GENS];
27 : : struct qat_dev_hw_spec_funcs *qat_dev_hw_spec[QAT_N_GENS];
28 : :
29 : : struct qat_service qat_service[QAT_MAX_SERVICES];
30 : :
31 : : /* per-process array of device data */
32 : : struct qat_device_info qat_pci_devs[RTE_PMD_QAT_MAX_PCI_DEVICES];
33 : : static int qat_nb_pci_devices;
34 : :
35 : : /*
36 : : * The set of PCI devices this driver supports
37 : : */
38 : :
39 : : static const struct rte_pci_id pci_id_qat_map[] = {
40 : : {
41 : : RTE_PCI_DEVICE(0x8086, 0x0443),
42 : : },
43 : : {
44 : : RTE_PCI_DEVICE(0x8086, 0x37c9),
45 : : },
46 : : {
47 : : RTE_PCI_DEVICE(0x8086, 0x19e3),
48 : : },
49 : : {
50 : : RTE_PCI_DEVICE(0x8086, 0x6f55),
51 : : },
52 : : {
53 : : RTE_PCI_DEVICE(0x8086, 0x18ef),
54 : : },
55 : : {
56 : : RTE_PCI_DEVICE(0x8086, 0x18a1),
57 : : },
58 : : {
59 : : RTE_PCI_DEVICE(0x8086, 0x578b),
60 : : },
61 : : {
62 : : RTE_PCI_DEVICE(0x8086, 0x4941),
63 : : },
64 : : {
65 : : RTE_PCI_DEVICE(0x8086, 0x4943),
66 : : },
67 : : {
68 : : RTE_PCI_DEVICE(0x8086, 0x4945),
69 : : },
70 : : {
71 : : RTE_PCI_DEVICE(0x8086, 0x4947),
72 : : },
73 : : {
74 : : RTE_PCI_DEVICE(0x8086, 0x1454),
75 : : },
76 : : {
77 : : RTE_PCI_DEVICE(0x8086, 0x0da5),
78 : : },
79 : : {.device_id = 0},
80 : : };
81 : :
82 : : static int
83 : : qat_pci_get_extra_size(enum qat_device_gen qat_dev_gen)
84 : : {
85 : 0 : struct qat_dev_hw_spec_funcs *ops_hw =
86 : : qat_dev_hw_spec[qat_dev_gen];
87 [ # # ]: 0 : if (ops_hw->qat_dev_get_extra_size == NULL)
88 : : return -ENOTSUP;
89 : 0 : return ops_hw->qat_dev_get_extra_size();
90 : : }
91 : :
92 : : static struct qat_pci_device *
93 : 0 : qat_pci_get_named_dev(const char *name)
94 : : {
95 : : unsigned int i;
96 : :
97 [ # # ]: 0 : if (name == NULL)
98 : : return NULL;
99 : :
100 [ # # ]: 0 : for (i = 0; i < RTE_PMD_QAT_MAX_PCI_DEVICES; i++) {
101 [ # # ]: 0 : if (qat_pci_devs[i].mz &&
102 : 0 : (strcmp(((struct qat_pci_device *)
103 [ # # ]: 0 : qat_pci_devs[i].mz->addr)->name, name)
104 : : == 0))
105 : 0 : return (struct qat_pci_device *)
106 : : qat_pci_devs[i].mz->addr;
107 : : }
108 : :
109 : : return NULL;
110 : : }
111 : :
112 : : static uint8_t
113 : : qat_pci_find_free_device_index(void)
114 : : {
115 : : uint8_t dev_id;
116 : :
117 [ # # ]: 0 : for (dev_id = 0; dev_id < RTE_PMD_QAT_MAX_PCI_DEVICES;
118 : 0 : dev_id++) {
119 [ # # ]: 0 : if (qat_pci_devs[dev_id].mz == NULL)
120 : : break;
121 : : }
122 : : return dev_id;
123 : : }
124 : :
125 : : static struct qat_pci_device *
126 : : qat_get_qat_dev_from_pci_dev(struct rte_pci_device *pci_dev)
127 : : {
128 : : char name[QAT_DEV_NAME_MAX_LEN];
129 : :
130 : 0 : rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
131 : :
132 : 0 : return qat_pci_get_named_dev(name);
133 : : }
134 : :
135 : : static enum qat_device_gen
136 : 0 : pick_gen(const struct rte_pci_device *pci_dev)
137 : : {
138 [ # # # # : 0 : switch (pci_dev->id.device_id) {
# # # # ]
139 : : case 0x0443:
140 : : return QAT_GEN1;
141 : 0 : case 0x37c9:
142 : : case 0x19e3:
143 : : case 0x6f55:
144 : : case 0x18ef:
145 : 0 : return QAT_GEN2;
146 : 0 : case 0x18a1:
147 : : case 0x578b:
148 : 0 : return QAT_GEN3;
149 : 0 : case 0x4941:
150 : : case 0x4943:
151 : : case 0x4945:
152 : 0 : return QAT_GEN4;
153 : 0 : case 0x4947:
154 : 0 : return QAT_GEN5;
155 : 0 : case 0x1454:
156 : 0 : return QAT_GEN_LCE;
157 : 0 : case 0x0da5:
158 : 0 : return QAT_VQAT;
159 : 0 : default:
160 : 0 : QAT_LOG(ERR, "Invalid dev_id, can't determine generation");
161 : 0 : return QAT_N_GENS;
162 : : }
163 : : }
164 : :
165 : : static int
166 : : wireless_slice_support(uint16_t pci_dev_id)
167 : : {
168 : 0 : return pci_dev_id == 0x578b ||
169 : 0 : pci_dev_id == 0x4947;
170 : : }
171 : :
172 : : /* This function base on the atoi function peculiarity, non integral part
173 : : * other than the equals sign is ignored. It will not work with other conversion
174 : : * functions like strt*.
175 : : */
176 : 0 : const char *qat_dev_cmdline_get_val(struct qat_pci_device *qat_dev,
177 : : const char *key)
178 : : {
179 [ # # ]: 0 : if (qat_dev->command_line == NULL)
180 : : return NULL;
181 : 0 : key = strstr(qat_dev->command_line, key);
182 : : /* At this point, a key should be validated */
183 [ # # ]: 0 : return key ? strchr(key, '=') + 1 : NULL;
184 : : }
185 : :
186 : 0 : static int cmdline_validate(const char *arg)
187 : : {
188 : 0 : const char *eq_sign = strchr(arg, '=');
189 : : int i, len;
190 : :
191 : : /* Check for the equal sign */
192 [ # # ]: 0 : if (eq_sign == NULL) {
193 : 0 : QAT_LOG(ERR, "malformed string, no equals sign, %s", arg);
194 : 0 : return 0;
195 : : }
196 : : /* Check if an argument is not empty */
197 : 0 : len = strlen(eq_sign) - 1;
198 [ # # ]: 0 : if (len == 0) {
199 : 0 : QAT_LOG(ERR, "malformed string, empty argument, %s", arg);
200 : 0 : return 0;
201 : : }
202 : 0 : len = eq_sign - arg;
203 [ # # ]: 0 : for (i = 0; i < QAT_MAX_SERVICES + 1; i++) {
204 : : int j = 0;
205 : : const char *def = NULL;
206 : :
207 [ # # ]: 0 : if (!qat_cmdline_defines[i])
208 : 0 : continue;
209 [ # # ]: 0 : while ((def = qat_cmdline_defines[i][j++])) {
210 [ # # ]: 0 : if (strncmp(def, arg, len))
211 : 0 : continue;
212 : 0 : QAT_LOG(DEBUG, "Found %s command line argument",
213 : : def);
214 : 0 : return 1;
215 : : }
216 : : }
217 : : return 0;
218 : : }
219 : :
220 : : static int
221 : 0 : qat_dev_parse_command_line(struct qat_pci_device *qat_dev,
222 : : struct rte_devargs *devargs)
223 : : {
224 : : int len = 0;
225 : : char *token = NULL;
226 : :
227 [ # # ]: 0 : if (!devargs)
228 : : return 0;
229 : :
230 : 0 : len = strlen(devargs->drv_str);
231 [ # # ]: 0 : if (len == 0)
232 : : return 0;
233 : 0 : ++len;
234 : : /* Allocate per-device command line */
235 : 0 : qat_dev->command_line = rte_malloc(NULL, len, 0);
236 [ # # ]: 0 : if (qat_dev->command_line == NULL) {
237 : 0 : QAT_LOG(ERR, "Cannot allocate memory for command line");
238 : 0 : return -1;
239 : : }
240 : 0 : strcpy(qat_dev->command_line, devargs->drv_str);
241 : 0 : token = strtok(qat_dev->command_line, ",");
242 [ # # ]: 0 : while (token != NULL) {
243 [ # # ]: 0 : if (!cmdline_validate(token)) {
244 : 0 : QAT_LOG(ERR, "Incorrect command line argument: %s",
245 : : token);
246 : 0 : return -1;
247 : : }
248 : 0 : token = strtok(NULL, ",");
249 : : }
250 : : /* Copy once againe the entire string, strtok already altered the contents */
251 : 0 : strcpy(qat_dev->command_line, devargs->drv_str);
252 : 0 : return 0;
253 : : }
254 : :
255 : : static struct qat_pci_device *
256 : 0 : qat_pci_device_allocate(struct rte_pci_device *pci_dev)
257 : : {
258 : : struct qat_pci_device *qat_dev;
259 : : enum qat_device_gen qat_dev_gen;
260 : : uint8_t qat_dev_id = 0;
261 : : char name[QAT_DEV_NAME_MAX_LEN];
262 : 0 : struct rte_devargs *devargs = pci_dev->device.devargs;
263 : : struct qat_dev_hw_spec_funcs *ops_hw;
264 : : struct rte_mem_resource *mem_resource;
265 : : const struct rte_memzone *qat_dev_mz;
266 : : int qat_dev_size, extra_size;
267 : : const char *cmdline = NULL;
268 : :
269 : 0 : rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
270 : 0 : snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
271 : :
272 : 0 : qat_dev_gen = pick_gen(pci_dev);
273 [ # # ]: 0 : if (qat_dev_gen == QAT_N_GENS) {
274 : 0 : QAT_LOG(ERR, "Invalid dev_id, can't determine generation");
275 : 0 : return NULL;
276 : : }
277 : :
278 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
279 : 0 : const struct rte_memzone *mz = rte_memzone_lookup(name);
280 : :
281 [ # # ]: 0 : if (mz == NULL) {
282 : 0 : QAT_LOG(ERR,
283 : : "Secondary can't find %s mz, did primary create device?",
284 : : name);
285 : 0 : return NULL;
286 : : }
287 : 0 : qat_dev = mz->addr;
288 : 0 : qat_pci_devs[qat_dev->qat_dev_id].mz = mz;
289 : 0 : qat_pci_devs[qat_dev->qat_dev_id].pci_dev = pci_dev;
290 : 0 : qat_nb_pci_devices++;
291 : 0 : QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
292 : : qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
293 : 0 : return qat_dev;
294 : : }
295 : :
296 [ # # ]: 0 : if (qat_pci_get_named_dev(name) != NULL) {
297 : 0 : QAT_LOG(ERR, "QAT device with name %s already allocated!",
298 : : name);
299 : 0 : return NULL;
300 : : }
301 : :
302 : : qat_dev_id = qat_pci_find_free_device_index();
303 [ # # ]: 0 : if (qat_dev_id == RTE_PMD_QAT_MAX_PCI_DEVICES) {
304 : 0 : QAT_LOG(ERR, "Reached maximum number of QAT devices");
305 : 0 : return NULL;
306 : : }
307 : :
308 : : extra_size = qat_pci_get_extra_size(qat_dev_gen);
309 [ # # ]: 0 : if (extra_size < 0) {
310 : 0 : QAT_LOG(ERR, "QAT internal error: no pci pointer for gen %d",
311 : : qat_dev_gen);
312 : 0 : return NULL;
313 : : }
314 : :
315 : 0 : qat_dev_size = sizeof(struct qat_pci_device) + sizeof(void *) *
316 : 0 : QAT_MAX_SERVICES + extra_size;
317 : 0 : qat_dev_mz = rte_memzone_reserve(name, qat_dev_size,
318 : 0 : rte_socket_id(), 0);
319 : :
320 [ # # ]: 0 : if (qat_dev_mz == NULL) {
321 : 0 : QAT_LOG(ERR, "Error when allocating memzone for QAT_%d",
322 : : qat_dev_id);
323 : 0 : return NULL;
324 : : }
325 : :
326 [ # # ]: 0 : qat_dev = qat_dev_mz->addr;
327 : : memset(qat_dev, 0, qat_dev_size);
328 : 0 : qat_dev->dev_private = qat_dev + 1;
329 [ # # ]: 0 : strlcpy(qat_dev->name, name, QAT_DEV_NAME_MAX_LEN);
330 : 0 : qat_dev->qat_dev_id = qat_dev_id;
331 : 0 : qat_dev->qat_dev_gen = qat_dev_gen;
332 : 0 : qat_pci_devs[qat_dev_id].pci_dev = pci_dev;
333 : :
334 [ # # ]: 0 : if (wireless_slice_support(pci_dev->id.device_id))
335 : 0 : qat_dev->options.has_wireless_slice = 1;
336 : :
337 : 0 : ops_hw = qat_dev_hw_spec[qat_dev->qat_dev_gen];
338 [ # # ]: 0 : NOT_NULL(ops_hw->qat_dev_get_misc_bar, goto error,
339 : : "QAT internal error! qat_dev_get_misc_bar function not set");
340 [ # # ]: 0 : if (ops_hw->qat_dev_get_misc_bar(&mem_resource, pci_dev) == 0) {
341 [ # # ]: 0 : if (mem_resource->addr == NULL) {
342 : 0 : QAT_LOG(ERR, "QAT cannot get access to VF misc bar");
343 : 0 : goto error;
344 : : }
345 : 0 : qat_dev->misc_bar_io_addr = mem_resource->addr;
346 : : } else
347 : 0 : qat_dev->misc_bar_io_addr = NULL;
348 : :
349 : : /* Parse the command line */
350 [ # # ]: 0 : if (qat_dev_parse_command_line(qat_dev, devargs))
351 : 0 : goto error;
352 : :
353 : : /* Parse the arguments */
354 : 0 : cmdline = qat_dev_cmdline_get_val(qat_dev, QAT_LEGACY_CAPA);
355 [ # # ]: 0 : if (cmdline)
356 : 0 : qat_dev->options.legacy_alg = atoi(cmdline);
357 : :
358 [ # # ]: 0 : if (qat_read_qp_config(qat_dev)) {
359 : 0 : QAT_LOG(ERR,
360 : : "Cannot acquire ring configuration for QAT_%d",
361 : : qat_dev_id);
362 : 0 : goto error;
363 : : }
364 [ # # ]: 0 : NOT_NULL(ops_hw->qat_dev_reset_ring_pairs, goto error,
365 : : "QAT internal error! Reset ring pairs function not set, gen : %d",
366 : : qat_dev_gen);
367 [ # # ]: 0 : if (ops_hw->qat_dev_reset_ring_pairs(qat_dev)) {
368 : 0 : QAT_LOG(ERR,
369 : : "Cannot reset ring pairs, does pf driver supports pf2vf comms?"
370 : : );
371 : 0 : goto error;
372 : : }
373 [ # # ]: 0 : NOT_NULL(ops_hw->qat_dev_get_slice_map, goto error,
374 : : "QAT internal error! Read slice function not set, gen : %d",
375 : : qat_dev_gen);
376 [ # # ]: 0 : if (ops_hw->qat_dev_get_slice_map(&qat_dev->options.slice_map, pci_dev) < 0) {
377 : 0 : QAT_LOG(ERR,
378 : : "Cannot read slice configuration");
379 : 0 : goto error;
380 : : }
381 : : rte_spinlock_init(&qat_dev->arb_csr_lock);
382 : :
383 : : /* No errors when allocating, attach memzone with
384 : : * qat_dev to list of devices
385 : : */
386 : 0 : qat_pci_devs[qat_dev_id].mz = qat_dev_mz;
387 : 0 : qat_nb_pci_devices++;
388 : :
389 : 0 : QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
390 : : qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
391 : :
392 : 0 : return qat_dev;
393 : 0 : error:
394 : 0 : rte_free(qat_dev->command_line);
395 : 0 : rte_memzone_free(qat_dev_mz);
396 : 0 : return NULL;
397 : : }
398 : :
399 : : static int
400 : 0 : qat_pci_device_release(struct rte_pci_device *pci_dev)
401 : : {
402 : : struct qat_pci_device *qat_dev;
403 : : char name[QAT_DEV_NAME_MAX_LEN];
404 : : int busy = 0, i;
405 : :
406 [ # # ]: 0 : if (pci_dev == NULL)
407 : : return -EINVAL;
408 : :
409 : 0 : rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
410 [ # # ]: 0 : snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
411 : 0 : qat_dev = qat_pci_get_named_dev(name);
412 [ # # ]: 0 : if (qat_dev != NULL) {
413 : :
414 : 0 : struct qat_device_info *inst =
415 : 0 : &qat_pci_devs[qat_dev->qat_dev_id];
416 : : /* Check that there are no service devs still on pci device */
417 : :
418 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
419 [ # # ]: 0 : for (i = 0; i < QAT_MAX_SERVICES; i++) {
420 [ # # ]: 0 : if (qat_dev->pmd[i] != NULL) {
421 : 0 : QAT_LOG(DEBUG, "QAT %s device %s is busy",
422 : : qat_service[i].name, name);
423 : : busy = 1;
424 : : }
425 : : }
426 [ # # ]: 0 : if (busy)
427 : : return -EBUSY;
428 : 0 : rte_memzone_free(inst->mz);
429 : : }
430 : : memset(inst, 0, sizeof(struct qat_device_info));
431 : 0 : qat_nb_pci_devices--;
432 : 0 : QAT_LOG(DEBUG, "QAT device %s released, total QATs %d",
433 : : name, qat_nb_pci_devices);
434 : : }
435 : : return 0;
436 : : }
437 : :
438 : : static int
439 : 0 : qat_pci_dev_destroy(struct qat_pci_device *qat_pci_dev,
440 : : struct rte_pci_device *pci_dev)
441 : : {
442 : : int i;
443 : :
444 [ # # ]: 0 : for (i = 0; i < QAT_MAX_SERVICES; i++) {
445 [ # # ]: 0 : if (!qat_service[i].dev_destroy)
446 : 0 : continue;
447 : 0 : qat_service[i].dev_destroy(qat_pci_dev);
448 : : }
449 : 0 : return qat_pci_device_release(pci_dev);
450 : : }
451 : :
452 : 0 : static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
453 : : struct rte_pci_device *pci_dev)
454 : : {
455 : : int i, ret = 0, num_pmds_created = 0;
456 : : struct qat_pci_device *qat_pci_dev;
457 : :
458 : 0 : QAT_LOG(DEBUG, "Found QAT device at %02x:%02x.%x",
459 : : pci_dev->addr.bus,
460 : : pci_dev->addr.devid,
461 : : pci_dev->addr.function);
462 : :
463 : 0 : qat_pci_dev = qat_pci_device_allocate(pci_dev);
464 [ # # ]: 0 : if (qat_pci_dev == NULL)
465 : : return -ENODEV;
466 : :
467 [ # # ]: 0 : for (i = 0; i < QAT_MAX_SERVICES; i++) {
468 [ # # ]: 0 : if (!qat_service[i].dev_create)
469 : 0 : continue;
470 : 0 : ret = qat_service[i].dev_create(qat_pci_dev);
471 [ # # ]: 0 : if (ret == 0)
472 : 0 : num_pmds_created++;
473 : : else {
474 : 0 : QAT_LOG(WARNING, "Failed to create %s PMD on device %s",
475 : : qat_service[i].name,
476 : : qat_pci_dev->name);
477 : : }
478 : : }
479 : :
480 [ # # ]: 0 : if (num_pmds_created == 0)
481 : 0 : qat_pci_dev_destroy(qat_pci_dev, pci_dev);
482 : :
483 : : return 0;
484 : : }
485 : :
486 : : static int
487 : 0 : qat_pci_remove(struct rte_pci_device *pci_dev)
488 : : {
489 : : struct qat_pci_device *qat_pci_dev;
490 : :
491 [ # # ]: 0 : if (pci_dev == NULL)
492 : : return -EINVAL;
493 : :
494 : : qat_pci_dev = qat_get_qat_dev_from_pci_dev(pci_dev);
495 [ # # ]: 0 : if (qat_pci_dev == NULL)
496 : : return 0;
497 : :
498 : 0 : return qat_pci_dev_destroy(qat_pci_dev, pci_dev);
499 : : }
500 : :
501 : : static struct rte_pci_driver rte_qat_pmd = {
502 : : .id_table = pci_id_qat_map,
503 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
504 : : .probe = qat_pci_probe,
505 : : .remove = qat_pci_remove
506 : : };
507 : :
508 : 254 : RTE_PMD_REGISTER_PCI(QAT_PCI_NAME, rte_qat_pmd);
509 : : RTE_PMD_REGISTER_PCI_TABLE(QAT_PCI_NAME, pci_id_qat_map);
510 : : RTE_PMD_REGISTER_KMOD_DEP(QAT_PCI_NAME, "* igb_uio | uio_pci_generic | vfio-pci");
|