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 : 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 : : int i, len;
189 : 0 : char *eq_sign = strchr(arg, '=');
190 : : /* Check for the equal sign */
191 [ # # ]: 0 : if (eq_sign == NULL) {
192 : 0 : QAT_LOG(ERR, "malformed string, no equals sign, %s", arg);
193 : 0 : return 0;
194 : : }
195 : : /* Check if an argument is not empty */
196 : 0 : len = strlen(eq_sign) - 1;
197 [ # # ]: 0 : if (len == 0) {
198 : 0 : QAT_LOG(ERR, "malformed string, empty argument, %s", arg);
199 : 0 : return 0;
200 : : }
201 : 0 : len = eq_sign - arg;
202 [ # # ]: 0 : for (i = 0; i < QAT_MAX_SERVICES + 1; i++) {
203 : : int j = 0;
204 : : const char *def = NULL;
205 : :
206 [ # # ]: 0 : if (!qat_cmdline_defines[i])
207 : 0 : continue;
208 [ # # ]: 0 : while ((def = qat_cmdline_defines[i][j++])) {
209 [ # # ]: 0 : if (strncmp(def, arg, len))
210 : 0 : continue;
211 : 0 : QAT_LOG(DEBUG, "Found %s command line argument",
212 : : def);
213 : 0 : return 1;
214 : : }
215 : : }
216 : : return 0;
217 : : }
218 : :
219 : : static int
220 : 0 : qat_dev_parse_command_line(struct qat_pci_device *qat_dev,
221 : : struct rte_devargs *devargs)
222 : : {
223 : : int len = 0;
224 : : char *token = NULL;
225 : :
226 [ # # ]: 0 : if (!devargs)
227 : : return 0;
228 : :
229 : 0 : len = strlen(devargs->drv_str);
230 [ # # ]: 0 : if (len == 0)
231 : : return 0;
232 : 0 : ++len;
233 : : /* Allocate per-device command line */
234 : 0 : qat_dev->command_line = rte_malloc(NULL, len, 0);
235 [ # # ]: 0 : if (qat_dev->command_line == NULL) {
236 : 0 : QAT_LOG(ERR, "Cannot allocate memory for command line");
237 : 0 : return -1;
238 : : }
239 : 0 : strcpy(qat_dev->command_line, devargs->drv_str);
240 : 0 : token = strtok(qat_dev->command_line, ",");
241 [ # # ]: 0 : while (token != NULL) {
242 [ # # ]: 0 : if (!cmdline_validate(token)) {
243 : 0 : QAT_LOG(ERR, "Incorrect command line argument: %s",
244 : : token);
245 : 0 : return -1;
246 : : }
247 : 0 : token = strtok(NULL, ",");
248 : : }
249 : : /* Copy once againe the entire string, strtok already altered the contents */
250 : 0 : strcpy(qat_dev->command_line, devargs->drv_str);
251 : 0 : return 0;
252 : : }
253 : :
254 : : static struct qat_pci_device *
255 : 0 : qat_pci_device_allocate(struct rte_pci_device *pci_dev)
256 : : {
257 : : struct qat_pci_device *qat_dev;
258 : : enum qat_device_gen qat_dev_gen;
259 : : uint8_t qat_dev_id = 0;
260 : : char name[QAT_DEV_NAME_MAX_LEN];
261 : 0 : struct rte_devargs *devargs = pci_dev->device.devargs;
262 : : struct qat_dev_hw_spec_funcs *ops_hw;
263 : : struct rte_mem_resource *mem_resource;
264 : : const struct rte_memzone *qat_dev_mz;
265 : : int qat_dev_size, extra_size;
266 : : char *cmdline = NULL;
267 : :
268 : 0 : rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
269 : 0 : snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
270 : :
271 : 0 : qat_dev_gen = pick_gen(pci_dev);
272 [ # # ]: 0 : if (qat_dev_gen == QAT_N_GENS) {
273 : 0 : QAT_LOG(ERR, "Invalid dev_id, can't determine generation");
274 : 0 : return NULL;
275 : : }
276 : :
277 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
278 : 0 : const struct rte_memzone *mz = rte_memzone_lookup(name);
279 : :
280 [ # # ]: 0 : if (mz == NULL) {
281 : 0 : QAT_LOG(ERR,
282 : : "Secondary can't find %s mz, did primary create device?",
283 : : name);
284 : 0 : return NULL;
285 : : }
286 : 0 : qat_dev = mz->addr;
287 : 0 : qat_pci_devs[qat_dev->qat_dev_id].mz = mz;
288 : 0 : qat_pci_devs[qat_dev->qat_dev_id].pci_dev = pci_dev;
289 : 0 : qat_nb_pci_devices++;
290 : 0 : QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
291 : : qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
292 : 0 : return qat_dev;
293 : : }
294 : :
295 [ # # ]: 0 : if (qat_pci_get_named_dev(name) != NULL) {
296 : 0 : QAT_LOG(ERR, "QAT device with name %s already allocated!",
297 : : name);
298 : 0 : return NULL;
299 : : }
300 : :
301 : : qat_dev_id = qat_pci_find_free_device_index();
302 [ # # ]: 0 : if (qat_dev_id == RTE_PMD_QAT_MAX_PCI_DEVICES) {
303 : 0 : QAT_LOG(ERR, "Reached maximum number of QAT devices");
304 : 0 : return NULL;
305 : : }
306 : :
307 : : extra_size = qat_pci_get_extra_size(qat_dev_gen);
308 [ # # ]: 0 : if (extra_size < 0) {
309 : 0 : QAT_LOG(ERR, "QAT internal error: no pci pointer for gen %d",
310 : : qat_dev_gen);
311 : 0 : return NULL;
312 : : }
313 : :
314 : 0 : qat_dev_size = sizeof(struct qat_pci_device) + sizeof(void *) *
315 : 0 : QAT_MAX_SERVICES + extra_size;
316 : 0 : qat_dev_mz = rte_memzone_reserve(name, qat_dev_size,
317 : 0 : rte_socket_id(), 0);
318 : :
319 [ # # ]: 0 : if (qat_dev_mz == NULL) {
320 : 0 : QAT_LOG(ERR, "Error when allocating memzone for QAT_%d",
321 : : qat_dev_id);
322 : 0 : return NULL;
323 : : }
324 : :
325 [ # # ]: 0 : qat_dev = qat_dev_mz->addr;
326 : : memset(qat_dev, 0, qat_dev_size);
327 : 0 : qat_dev->dev_private = qat_dev + 1;
328 [ # # ]: 0 : strlcpy(qat_dev->name, name, QAT_DEV_NAME_MAX_LEN);
329 : 0 : qat_dev->qat_dev_id = qat_dev_id;
330 : 0 : qat_dev->qat_dev_gen = qat_dev_gen;
331 : 0 : qat_pci_devs[qat_dev_id].pci_dev = pci_dev;
332 : :
333 [ # # ]: 0 : if (wireless_slice_support(pci_dev->id.device_id))
334 : 0 : qat_dev->options.has_wireless_slice = 1;
335 : :
336 : 0 : ops_hw = qat_dev_hw_spec[qat_dev->qat_dev_gen];
337 [ # # ]: 0 : NOT_NULL(ops_hw->qat_dev_get_misc_bar, goto error,
338 : : "QAT internal error! qat_dev_get_misc_bar function not set");
339 [ # # ]: 0 : if (ops_hw->qat_dev_get_misc_bar(&mem_resource, pci_dev) == 0) {
340 [ # # ]: 0 : if (mem_resource->addr == NULL) {
341 : 0 : QAT_LOG(ERR, "QAT cannot get access to VF misc bar");
342 : 0 : goto error;
343 : : }
344 : 0 : qat_dev->misc_bar_io_addr = mem_resource->addr;
345 : : } else
346 : 0 : qat_dev->misc_bar_io_addr = NULL;
347 : :
348 : : /* Parse the command line */
349 [ # # ]: 0 : if (qat_dev_parse_command_line(qat_dev, devargs))
350 : 0 : goto error;
351 : :
352 : : /* Parse the arguments */
353 : 0 : cmdline = qat_dev_cmdline_get_val(qat_dev, QAT_LEGACY_CAPA);
354 [ # # ]: 0 : if (cmdline)
355 : 0 : qat_dev->options.legacy_alg = atoi(cmdline);
356 : :
357 [ # # ]: 0 : if (qat_read_qp_config(qat_dev)) {
358 : 0 : QAT_LOG(ERR,
359 : : "Cannot acquire ring configuration for QAT_%d",
360 : : qat_dev_id);
361 : 0 : goto error;
362 : : }
363 [ # # ]: 0 : NOT_NULL(ops_hw->qat_dev_reset_ring_pairs, goto error,
364 : : "QAT internal error! Reset ring pairs function not set, gen : %d",
365 : : qat_dev_gen);
366 [ # # ]: 0 : if (ops_hw->qat_dev_reset_ring_pairs(qat_dev)) {
367 : 0 : QAT_LOG(ERR,
368 : : "Cannot reset ring pairs, does pf driver supports pf2vf comms?"
369 : : );
370 : 0 : goto error;
371 : : }
372 [ # # ]: 0 : NOT_NULL(ops_hw->qat_dev_get_slice_map, goto error,
373 : : "QAT internal error! Read slice function not set, gen : %d",
374 : : qat_dev_gen);
375 [ # # ]: 0 : if (ops_hw->qat_dev_get_slice_map(&qat_dev->options.slice_map, pci_dev) < 0) {
376 : 0 : QAT_LOG(ERR,
377 : : "Cannot read slice configuration");
378 : 0 : goto error;
379 : : }
380 : : rte_spinlock_init(&qat_dev->arb_csr_lock);
381 : :
382 : : /* No errors when allocating, attach memzone with
383 : : * qat_dev to list of devices
384 : : */
385 : 0 : qat_pci_devs[qat_dev_id].mz = qat_dev_mz;
386 : 0 : qat_nb_pci_devices++;
387 : :
388 : 0 : QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
389 : : qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
390 : :
391 : 0 : return qat_dev;
392 : 0 : error:
393 : 0 : rte_free(qat_dev->command_line);
394 : 0 : rte_memzone_free(qat_dev_mz);
395 : 0 : return NULL;
396 : : }
397 : :
398 : : static int
399 : 0 : qat_pci_device_release(struct rte_pci_device *pci_dev)
400 : : {
401 : : struct qat_pci_device *qat_dev;
402 : : char name[QAT_DEV_NAME_MAX_LEN];
403 : : int busy = 0, i;
404 : :
405 [ # # ]: 0 : if (pci_dev == NULL)
406 : : return -EINVAL;
407 : :
408 : 0 : rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
409 [ # # ]: 0 : snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
410 : 0 : qat_dev = qat_pci_get_named_dev(name);
411 [ # # ]: 0 : if (qat_dev != NULL) {
412 : :
413 : 0 : struct qat_device_info *inst =
414 : 0 : &qat_pci_devs[qat_dev->qat_dev_id];
415 : : /* Check that there are no service devs still on pci device */
416 : :
417 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
418 [ # # ]: 0 : for (i = 0; i < QAT_MAX_SERVICES; i++) {
419 [ # # ]: 0 : if (qat_dev->pmd[i] != NULL) {
420 : 0 : QAT_LOG(DEBUG, "QAT %s device %s is busy",
421 : : qat_service[i].name, name);
422 : : busy = 1;
423 : : }
424 : : }
425 [ # # ]: 0 : if (busy)
426 : : return -EBUSY;
427 : 0 : rte_memzone_free(inst->mz);
428 : : }
429 : : memset(inst, 0, sizeof(struct qat_device_info));
430 : 0 : qat_nb_pci_devices--;
431 : 0 : QAT_LOG(DEBUG, "QAT device %s released, total QATs %d",
432 : : name, qat_nb_pci_devices);
433 : : }
434 : : return 0;
435 : : }
436 : :
437 : : static int
438 : 0 : qat_pci_dev_destroy(struct qat_pci_device *qat_pci_dev,
439 : : struct rte_pci_device *pci_dev)
440 : : {
441 : : int i;
442 : :
443 [ # # ]: 0 : for (i = 0; i < QAT_MAX_SERVICES; i++) {
444 [ # # ]: 0 : if (!qat_service[i].dev_destroy)
445 : 0 : continue;
446 : 0 : qat_service[i].dev_destroy(qat_pci_dev);
447 : : }
448 : 0 : return qat_pci_device_release(pci_dev);
449 : : }
450 : :
451 : 0 : static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
452 : : struct rte_pci_device *pci_dev)
453 : : {
454 : : int i, ret = 0, num_pmds_created = 0;
455 : : struct qat_pci_device *qat_pci_dev;
456 : :
457 : 0 : QAT_LOG(DEBUG, "Found QAT device at %02x:%02x.%x",
458 : : pci_dev->addr.bus,
459 : : pci_dev->addr.devid,
460 : : pci_dev->addr.function);
461 : :
462 : 0 : qat_pci_dev = qat_pci_device_allocate(pci_dev);
463 [ # # ]: 0 : if (qat_pci_dev == NULL)
464 : : return -ENODEV;
465 : :
466 [ # # ]: 0 : for (i = 0; i < QAT_MAX_SERVICES; i++) {
467 [ # # ]: 0 : if (!qat_service[i].dev_create)
468 : 0 : continue;
469 : 0 : ret = qat_service[i].dev_create(qat_pci_dev);
470 [ # # ]: 0 : if (ret == 0)
471 : 0 : num_pmds_created++;
472 : : else {
473 : 0 : QAT_LOG(WARNING, "Failed to create %s PMD on device %s",
474 : : qat_service[i].name,
475 : : qat_pci_dev->name);
476 : : }
477 : : }
478 : :
479 [ # # ]: 0 : if (num_pmds_created == 0)
480 : 0 : qat_pci_dev_destroy(qat_pci_dev, pci_dev);
481 : :
482 : : return 0;
483 : : }
484 : :
485 : : static int
486 : 0 : qat_pci_remove(struct rte_pci_device *pci_dev)
487 : : {
488 : : struct qat_pci_device *qat_pci_dev;
489 : :
490 [ # # ]: 0 : if (pci_dev == NULL)
491 : : return -EINVAL;
492 : :
493 : : qat_pci_dev = qat_get_qat_dev_from_pci_dev(pci_dev);
494 [ # # ]: 0 : if (qat_pci_dev == NULL)
495 : : return 0;
496 : :
497 : 0 : return qat_pci_dev_destroy(qat_pci_dev, pci_dev);
498 : : }
499 : :
500 : : static struct rte_pci_driver rte_qat_pmd = {
501 : : .id_table = pci_id_qat_map,
502 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
503 : : .probe = qat_pci_probe,
504 : : .remove = qat_pci_remove
505 : : };
506 : :
507 : 252 : RTE_PMD_REGISTER_PCI(QAT_PCI_NAME, rte_qat_pmd);
508 : : RTE_PMD_REGISTER_PCI_TABLE(QAT_PCI_NAME, pci_id_qat_map);
509 : : RTE_PMD_REGISTER_KMOD_DEP(QAT_PCI_NAME, "* igb_uio | uio_pci_generic | vfio-pci");
|