Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright 2017-2020 NXP
4 : : *
5 : : */
6 : : /* System headers */
7 : : #include <stdio.h>
8 : : #include <inttypes.h>
9 : : #include <unistd.h>
10 : : #include <limits.h>
11 : : #include <sched.h>
12 : : #include <signal.h>
13 : : #include <pthread.h>
14 : : #include <sys/types.h>
15 : : #include <sys/eventfd.h>
16 : :
17 : : #include <rte_byteorder.h>
18 : : #include <rte_common.h>
19 : : #include <rte_interrupts.h>
20 : : #include <rte_log.h>
21 : : #include <rte_debug.h>
22 : : #include <rte_atomic.h>
23 : : #include <rte_branch_prediction.h>
24 : : #include <rte_memory.h>
25 : : #include <rte_tailq.h>
26 : : #include <rte_eal.h>
27 : : #include <rte_alarm.h>
28 : : #include <rte_ether.h>
29 : : #include <ethdev_driver.h>
30 : : #include <rte_malloc.h>
31 : : #include <rte_ring.h>
32 : : #include <bus_driver.h>
33 : : #include <rte_mbuf_pool_ops.h>
34 : : #include <rte_mbuf_dyn.h>
35 : :
36 : : #include <dpaa_of.h>
37 : : #include <bus_dpaa_driver.h>
38 : : #include <rte_dpaa_logs.h>
39 : : #include <dpaax_iova_table.h>
40 : :
41 : : #include <fsl_usd.h>
42 : : #include <fsl_qman.h>
43 : : #include <fsl_bman.h>
44 : : #include <netcfg.h>
45 : :
46 : : struct rte_dpaa_bus {
47 : : struct rte_bus bus;
48 : : TAILQ_HEAD(, rte_dpaa_device) device_list;
49 : : TAILQ_HEAD(, rte_dpaa_driver) driver_list;
50 : : int device_count;
51 : : int detected;
52 : : };
53 : :
54 : : static struct rte_dpaa_bus rte_dpaa_bus;
55 : : struct netcfg_info *dpaa_netcfg;
56 : :
57 : : /* define a variable to hold the portal_key, once created.*/
58 : : static pthread_key_t dpaa_portal_key;
59 : :
60 : : unsigned int dpaa_svr_family;
61 : :
62 : : #define FSL_DPAA_BUS_NAME dpaa_bus
63 : :
64 : : RTE_DEFINE_PER_LCORE(struct dpaa_portal *, dpaa_io);
65 : :
66 : : #define DPAA_SEQN_DYNFIELD_NAME "dpaa_seqn_dynfield"
67 : : int dpaa_seqn_dynfield_offset = -1;
68 : :
69 : : struct fm_eth_port_cfg *
70 : 0 : dpaa_get_eth_port_cfg(int dev_id)
71 : : {
72 : 0 : return &dpaa_netcfg->port_cfg[dev_id];
73 : : }
74 : :
75 : : static int
76 : : compare_dpaa_devices(struct rte_dpaa_device *dev1,
77 : : struct rte_dpaa_device *dev2)
78 : : {
79 : : int comp = 0;
80 : :
81 : : /* Segregating ETH from SEC devices */
82 : 0 : if (dev1->device_type > dev2->device_type)
83 : : comp = 1;
84 [ # # ]: 0 : else if (dev1->device_type < dev2->device_type)
85 : : comp = -1;
86 : : else
87 : : comp = 0;
88 : :
89 [ # # ]: 0 : if ((comp != 0) || (dev1->device_type != FSL_DPAA_ETH))
90 : : return comp;
91 : :
92 [ # # ]: 0 : if (dev1->id.fman_id > dev2->id.fman_id) {
93 : : comp = 1;
94 [ # # ]: 0 : } else if (dev1->id.fman_id < dev2->id.fman_id) {
95 : : comp = -1;
96 : : } else {
97 : : /* FMAN ids match, check for mac_id */
98 [ # # ]: 0 : if (dev1->id.mac_id > dev2->id.mac_id)
99 : : comp = 1;
100 [ # # ]: 0 : else if (dev1->id.mac_id < dev2->id.mac_id)
101 : : comp = -1;
102 : : else
103 : : comp = 0;
104 : : }
105 : :
106 : : return comp;
107 : : }
108 : :
109 : : static inline void
110 : 0 : dpaa_add_to_device_list(struct rte_dpaa_device *newdev)
111 : : {
112 : : int comp, inserted = 0;
113 : : struct rte_dpaa_device *dev = NULL;
114 : : struct rte_dpaa_device *tdev = NULL;
115 : :
116 [ # # # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(dev, &rte_dpaa_bus.device_list, next, tdev) {
117 : : comp = compare_dpaa_devices(newdev, dev);
118 : : if (comp < 0) {
119 : 0 : TAILQ_INSERT_BEFORE(dev, newdev, next);
120 : : inserted = 1;
121 : : break;
122 : : }
123 : : }
124 : :
125 : : if (!inserted)
126 : 0 : TAILQ_INSERT_TAIL(&rte_dpaa_bus.device_list, newdev, next);
127 : 0 : }
128 : :
129 : : /*
130 : : * Reads the SEC device from DTS
131 : : * Returns -1 if SEC devices not available, 0 otherwise
132 : : */
133 : : static inline int
134 : : dpaa_sec_available(void)
135 : : {
136 : : const struct device_node *caam_node;
137 : :
138 [ # # ]: 0 : for_each_compatible_node(caam_node, NULL, "fsl,sec-v4.0") {
139 : : return 0;
140 : : }
141 : :
142 : : return -1;
143 : : }
144 : :
145 : : static void dpaa_clean_device_list(void);
146 : :
147 : : static struct rte_devargs *
148 : 0 : dpaa_devargs_lookup(struct rte_dpaa_device *dev)
149 : : {
150 : : struct rte_devargs *devargs;
151 : : char dev_name[32];
152 : :
153 [ # # ]: 0 : RTE_EAL_DEVARGS_FOREACH("dpaa_bus", devargs) {
154 : 0 : devargs->bus->parse(devargs->name, &dev_name);
155 [ # # ]: 0 : if (strcmp(dev_name, dev->device.name) == 0) {
156 : 0 : DPAA_BUS_INFO("**Devargs matched %s", dev_name);
157 : 0 : return devargs;
158 : : }
159 : : }
160 : : return NULL;
161 : : }
162 : :
163 : : static int
164 : 0 : dpaa_create_device_list(void)
165 : : {
166 : : int i;
167 : : int ret;
168 : : struct rte_dpaa_device *dev;
169 : : struct fm_eth_port_cfg *cfg;
170 : : struct fman_if *fman_intf;
171 : :
172 : : /* Creating Ethernet Devices */
173 [ # # ]: 0 : for (i = 0; i < dpaa_netcfg->num_ethports; i++) {
174 : 0 : dev = calloc(1, sizeof(struct rte_dpaa_device));
175 [ # # ]: 0 : if (!dev) {
176 : 0 : DPAA_BUS_LOG(ERR, "Failed to allocate ETH devices");
177 : : ret = -ENOMEM;
178 : 0 : goto cleanup;
179 : : }
180 : :
181 : 0 : dev->device.bus = &rte_dpaa_bus.bus;
182 : 0 : dev->device.numa_node = SOCKET_ID_ANY;
183 : :
184 : : /* Allocate interrupt handle instance */
185 : 0 : dev->intr_handle =
186 : 0 : rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
187 [ # # ]: 0 : if (dev->intr_handle == NULL) {
188 : 0 : DPAA_BUS_LOG(ERR, "Failed to allocate intr handle");
189 : : ret = -ENOMEM;
190 : 0 : goto cleanup;
191 : : }
192 : :
193 : 0 : cfg = &dpaa_netcfg->port_cfg[i];
194 : 0 : fman_intf = cfg->fman_if;
195 : :
196 : : /* Device identifiers */
197 : 0 : dev->id.fman_id = fman_intf->fman_idx + 1;
198 : 0 : dev->id.mac_id = fman_intf->mac_idx;
199 : 0 : dev->device_type = FSL_DPAA_ETH;
200 : 0 : dev->id.dev_id = i;
201 : :
202 : : /* Create device name */
203 : 0 : memset(dev->name, 0, RTE_ETH_NAME_MAX_LEN);
204 : 0 : sprintf(dev->name, "fm%d-mac%d", (fman_intf->fman_idx + 1),
205 : 0 : fman_intf->mac_idx);
206 : 0 : DPAA_BUS_LOG(INFO, "%s netdev added", dev->name);
207 : 0 : dev->device.name = dev->name;
208 : 0 : dev->device.devargs = dpaa_devargs_lookup(dev);
209 : :
210 : 0 : dpaa_add_to_device_list(dev);
211 : : }
212 : :
213 : 0 : rte_dpaa_bus.device_count = i;
214 : :
215 : : /* Unlike case of ETH, RTE_LIBRTE_DPAA_MAX_CRYPTODEV SEC devices are
216 : : * constantly created only if "sec" property is found in the device
217 : : * tree. Logically there is no limit for number of devices (QI
218 : : * interfaces) that can be created.
219 : : */
220 : :
221 : : if (dpaa_sec_available()) {
222 : 0 : DPAA_BUS_LOG(INFO, "DPAA SEC devices are not available");
223 : 0 : return 0;
224 : : }
225 : :
226 : : /* Creating SEC Devices */
227 [ # # ]: 0 : for (i = 0; i < RTE_LIBRTE_DPAA_MAX_CRYPTODEV; i++) {
228 : 0 : dev = calloc(1, sizeof(struct rte_dpaa_device));
229 [ # # ]: 0 : if (!dev) {
230 : 0 : DPAA_BUS_LOG(ERR, "Failed to allocate SEC devices");
231 : : ret = -1;
232 : 0 : goto cleanup;
233 : : }
234 : :
235 : : /* Allocate interrupt handle instance */
236 : 0 : dev->intr_handle =
237 : 0 : rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
238 [ # # ]: 0 : if (dev->intr_handle == NULL) {
239 : 0 : DPAA_BUS_LOG(ERR, "Failed to allocate intr handle");
240 : : ret = -ENOMEM;
241 : 0 : goto cleanup;
242 : : }
243 : :
244 : 0 : dev->device_type = FSL_DPAA_CRYPTO;
245 : 0 : dev->id.dev_id = rte_dpaa_bus.device_count + i;
246 : :
247 : : /* Even though RTE_CRYPTODEV_NAME_MAX_LEN is valid length of
248 : : * crypto PMD, using RTE_ETH_NAME_MAX_LEN as that is the size
249 : : * allocated for dev->name/
250 : : */
251 : 0 : memset(dev->name, 0, RTE_ETH_NAME_MAX_LEN);
252 : 0 : sprintf(dev->name, "dpaa_sec-%d", i+1);
253 : 0 : DPAA_BUS_LOG(INFO, "%s cryptodev added", dev->name);
254 : 0 : dev->device.name = dev->name;
255 : 0 : dev->device.devargs = dpaa_devargs_lookup(dev);
256 : :
257 : 0 : dpaa_add_to_device_list(dev);
258 : : }
259 : :
260 : 0 : rte_dpaa_bus.device_count += i;
261 : :
262 : : /* Creating QDMA Device */
263 [ # # ]: 0 : for (i = 0; i < RTE_DPAA_QDMA_DEVICES; i++) {
264 : 0 : dev = calloc(1, sizeof(struct rte_dpaa_device));
265 [ # # ]: 0 : if (!dev) {
266 : 0 : DPAA_BUS_LOG(ERR, "Failed to allocate QDMA device");
267 : : ret = -1;
268 : 0 : goto cleanup;
269 : : }
270 : :
271 : 0 : dev->device_type = FSL_DPAA_QDMA;
272 : 0 : dev->id.dev_id = rte_dpaa_bus.device_count + i;
273 : :
274 : 0 : memset(dev->name, 0, RTE_ETH_NAME_MAX_LEN);
275 : : sprintf(dev->name, "dpaa_qdma-%d", i+1);
276 : 0 : DPAA_BUS_LOG(INFO, "%s qdma device added", dev->name);
277 : 0 : dev->device.name = dev->name;
278 : 0 : dev->device.devargs = dpaa_devargs_lookup(dev);
279 : :
280 : 0 : dpaa_add_to_device_list(dev);
281 : : }
282 : 0 : rte_dpaa_bus.device_count += i;
283 : :
284 : 0 : return 0;
285 : :
286 : 0 : cleanup:
287 : 0 : dpaa_clean_device_list();
288 : 0 : return ret;
289 : : }
290 : :
291 : : static void
292 : 0 : dpaa_clean_device_list(void)
293 : : {
294 : : struct rte_dpaa_device *dev = NULL;
295 : : struct rte_dpaa_device *tdev = NULL;
296 : :
297 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(dev, &rte_dpaa_bus.device_list, next, tdev) {
298 [ # # ]: 0 : TAILQ_REMOVE(&rte_dpaa_bus.device_list, dev, next);
299 : 0 : rte_intr_instance_free(dev->intr_handle);
300 : 0 : free(dev);
301 : : dev = NULL;
302 : : }
303 : 0 : }
304 : :
305 : 0 : int rte_dpaa_portal_init(void *arg)
306 : : {
307 : : static const struct rte_mbuf_dynfield dpaa_seqn_dynfield_desc = {
308 : : .name = DPAA_SEQN_DYNFIELD_NAME,
309 : : .size = sizeof(dpaa_seqn_t),
310 : : .align = __alignof__(dpaa_seqn_t),
311 : : };
312 : : unsigned int cpu, lcore = rte_lcore_id();
313 : : int ret;
314 : :
315 : 0 : BUS_INIT_FUNC_TRACE();
316 : :
317 [ # # ]: 0 : if ((size_t)arg == 1 || lcore == LCORE_ID_ANY)
318 : 0 : lcore = rte_get_main_lcore();
319 : : else
320 [ # # ]: 0 : if (lcore >= RTE_MAX_LCORE)
321 : : return -1;
322 : :
323 : 0 : cpu = rte_lcore_to_cpu_id(lcore);
324 : :
325 : 0 : dpaa_seqn_dynfield_offset =
326 : 0 : rte_mbuf_dynfield_register(&dpaa_seqn_dynfield_desc);
327 [ # # ]: 0 : if (dpaa_seqn_dynfield_offset < 0) {
328 : 0 : DPAA_BUS_LOG(ERR, "Failed to register mbuf field for dpaa sequence number\n");
329 : 0 : return -rte_errno;
330 : : }
331 : :
332 : : /* Initialise bman thread portals */
333 : 0 : ret = bman_thread_init();
334 [ # # ]: 0 : if (ret) {
335 : 0 : DPAA_BUS_LOG(ERR, "bman_thread_init failed on core %u"
336 : : " (lcore=%u) with ret: %d", cpu, lcore, ret);
337 : 0 : return ret;
338 : : }
339 : :
340 : 0 : DPAA_BUS_LOG(DEBUG, "BMAN thread initialized - CPU=%d lcore=%d",
341 : : cpu, lcore);
342 : :
343 : : /* Initialise qman thread portals */
344 : 0 : ret = qman_thread_init();
345 [ # # ]: 0 : if (ret) {
346 : 0 : DPAA_BUS_LOG(ERR, "qman_thread_init failed on core %u"
347 : : " (lcore=%u) with ret: %d", cpu, lcore, ret);
348 : 0 : bman_thread_finish();
349 : 0 : return ret;
350 : : }
351 : :
352 : 0 : DPAA_BUS_LOG(DEBUG, "QMAN thread initialized - CPU=%d lcore=%d",
353 : : cpu, lcore);
354 : :
355 : 0 : DPAA_PER_LCORE_PORTAL = rte_malloc(NULL, sizeof(struct dpaa_portal),
356 : : RTE_CACHE_LINE_SIZE);
357 [ # # ]: 0 : if (!DPAA_PER_LCORE_PORTAL) {
358 : 0 : DPAA_BUS_LOG(ERR, "Unable to allocate memory");
359 : 0 : bman_thread_finish();
360 : 0 : qman_thread_finish();
361 : 0 : return -ENOMEM;
362 : : }
363 : :
364 : 0 : DPAA_PER_LCORE_PORTAL->qman_idx = qman_get_portal_index();
365 [ # # ]: 0 : DPAA_PER_LCORE_PORTAL->bman_idx = bman_get_portal_index();
366 : 0 : DPAA_PER_LCORE_PORTAL->tid = rte_gettid();
367 : :
368 : 0 : ret = pthread_setspecific(dpaa_portal_key,
369 : : (void *)DPAA_PER_LCORE_PORTAL);
370 [ # # ]: 0 : if (ret) {
371 : 0 : DPAA_BUS_LOG(ERR, "pthread_setspecific failed on core %u"
372 : : " (lcore=%u) with ret: %d", cpu, lcore, ret);
373 : 0 : dpaa_portal_finish(NULL);
374 : :
375 : 0 : return ret;
376 : : }
377 : :
378 : 0 : DPAA_BUS_LOG(DEBUG, "QMAN thread initialized");
379 : :
380 : 0 : return 0;
381 : : }
382 : :
383 : : int
384 : 0 : rte_dpaa_portal_fq_init(void *arg, struct qman_fq *fq)
385 : : {
386 : : /* Affine above created portal with channel*/
387 : : u32 sdqcr;
388 : : int ret;
389 : :
390 [ # # ]: 0 : if (unlikely(!DPAA_PER_LCORE_PORTAL)) {
391 : 0 : ret = rte_dpaa_portal_init(arg);
392 [ # # ]: 0 : if (ret < 0) {
393 : 0 : DPAA_BUS_LOG(ERR, "portal initialization failure");
394 : 0 : return ret;
395 : : }
396 : : }
397 : :
398 : : /* Initialise qman specific portals */
399 : 0 : ret = fsl_qman_fq_portal_init(fq->qp);
400 [ # # ]: 0 : if (ret) {
401 : 0 : DPAA_BUS_LOG(ERR, "Unable to init fq portal");
402 : 0 : return -1;
403 : : }
404 : :
405 : 0 : sdqcr = QM_SDQCR_CHANNELS_POOL_CONV(fq->ch_id);
406 : 0 : qman_static_dequeue_add(sdqcr, fq->qp);
407 : :
408 : 0 : return 0;
409 : : }
410 : :
411 : 0 : int rte_dpaa_portal_fq_close(struct qman_fq *fq)
412 : : {
413 : 0 : return fsl_qman_fq_portal_destroy(fq->qp);
414 : : }
415 : :
416 : : void
417 : 0 : dpaa_portal_finish(void *arg)
418 : : {
419 : : struct dpaa_portal *dpaa_io_portal = (struct dpaa_portal *)arg;
420 : :
421 [ # # ]: 0 : if (!dpaa_io_portal) {
422 : 0 : DPAA_BUS_LOG(DEBUG, "Portal already cleaned");
423 : 0 : return;
424 : : }
425 : :
426 : 0 : bman_thread_finish();
427 : 0 : qman_thread_finish();
428 : :
429 : 0 : pthread_setspecific(dpaa_portal_key, NULL);
430 : :
431 : 0 : rte_free(dpaa_io_portal);
432 : : dpaa_io_portal = NULL;
433 : 0 : DPAA_PER_LCORE_PORTAL = NULL;
434 : : }
435 : :
436 : : static int
437 : 34 : rte_dpaa_bus_parse(const char *name, void *out)
438 : : {
439 : : unsigned int i, j;
440 : : size_t delta;
441 : : size_t max_name_len;
442 : :
443 : : /* There are two ways of passing device name, with and without
444 : : * separator. "dpaa_bus:fm1-mac3" with separator, and "fm1-mac3"
445 : : * without separator. Both need to be handled.
446 : : * It is also possible that "name=fm1-mac3" is passed along.
447 : : */
448 : 34 : DPAA_BUS_DEBUG("Parse device name (%s)", name);
449 : :
450 : : delta = 0;
451 [ + - ]: 34 : if (strncmp(name, "dpaa_bus:", 9) == 0) {
452 : : delta = 9;
453 [ - + ]: 34 : } else if (strncmp(name, "name=", 5) == 0) {
454 : : delta = 5;
455 : : }
456 : :
457 [ - + ]: 34 : if (strncmp("dpaa_sec", &name[delta], 8) == 0) {
458 [ # # ]: 0 : if (sscanf(&name[delta], "dpaa_sec-%u", &i) != 1 ||
459 [ # # # # ]: 0 : i < 1 || i > 4)
460 : : return -EINVAL;
461 : : max_name_len = sizeof("dpaa_sec-.") - 1;
462 : : } else {
463 [ - + ]: 34 : if (sscanf(&name[delta], "fm%u-mac%u", &i, &j) != 2 ||
464 [ # # # # ]: 0 : i >= 2 || j >= 16)
465 : : return -EINVAL;
466 : :
467 : : max_name_len = sizeof("fm.-mac..") - 1;
468 : : }
469 : :
470 [ # # ]: 0 : if (out != NULL) {
471 : : char *out_name = out;
472 : :
473 : : /* Do not check for truncation, either name ends with
474 : : * '\0' or the device name is followed by parameters and there
475 : : * will be a ',' instead. Not copying past this comma is not an
476 : : * error.
477 : : */
478 [ # # ]: 0 : strlcpy(out_name, &name[delta], max_name_len + 1);
479 : :
480 : : /* Second digit of mac%u could instead be ','. */
481 [ # # ]: 0 : if ((strlen(out_name) == max_name_len) &&
482 [ # # ]: 0 : out_name[max_name_len] == ',')
483 : 0 : out_name[max_name_len] = '\0';
484 : : }
485 : :
486 : : return 0;
487 : : }
488 : :
489 : : #define DPAA_DEV_PATH1 "/sys/devices/platform/soc/soc:fsl,dpaa"
490 : : #define DPAA_DEV_PATH2 "/sys/devices/platform/fsl,dpaa"
491 : :
492 : : static int
493 : 169 : rte_dpaa_bus_scan(void)
494 : : {
495 : : int ret;
496 : :
497 : 169 : BUS_INIT_FUNC_TRACE();
498 : :
499 [ + - + - ]: 338 : if ((access(DPAA_DEV_PATH1, F_OK) != 0) &&
500 : 169 : (access(DPAA_DEV_PATH2, F_OK) != 0)) {
501 : 169 : RTE_LOG(DEBUG, EAL, "DPAA Bus not present. Skipping.\n");
502 : 169 : return 0;
503 : : }
504 : :
505 [ # # ]: 0 : if (rte_dpaa_bus.detected)
506 : : return 0;
507 : :
508 : 0 : rte_dpaa_bus.detected = 1;
509 : :
510 : : /* create the key, supplying a function that'll be invoked
511 : : * when a portal affined thread will be deleted.
512 : : */
513 : 0 : ret = pthread_key_create(&dpaa_portal_key, dpaa_portal_finish);
514 [ # # ]: 0 : if (ret) {
515 : 0 : DPAA_BUS_LOG(DEBUG, "Unable to create pthread key. (%d)", ret);
516 : 0 : dpaa_clean_device_list();
517 : 0 : return ret;
518 : : }
519 : :
520 : : return 0;
521 : : }
522 : :
523 : : /* register a dpaa bus based dpaa driver */
524 : : void
525 : 705 : rte_dpaa_driver_register(struct rte_dpaa_driver *driver)
526 : : {
527 [ - + ]: 705 : RTE_VERIFY(driver);
528 : :
529 : 705 : BUS_INIT_FUNC_TRACE();
530 : :
531 : 705 : TAILQ_INSERT_TAIL(&rte_dpaa_bus.driver_list, driver, next);
532 : 705 : }
533 : :
534 : : /* un-register a dpaa bus based dpaa driver */
535 : : void
536 : 0 : rte_dpaa_driver_unregister(struct rte_dpaa_driver *driver)
537 : : {
538 : 0 : BUS_INIT_FUNC_TRACE();
539 : :
540 [ # # ]: 0 : TAILQ_REMOVE(&rte_dpaa_bus.driver_list, driver, next);
541 : 0 : }
542 : :
543 : : static int
544 : 0 : rte_dpaa_device_match(struct rte_dpaa_driver *drv,
545 : : struct rte_dpaa_device *dev)
546 : : {
547 [ # # ]: 0 : if (!drv || !dev) {
548 : 0 : DPAA_BUS_DEBUG("Invalid drv or dev received.");
549 : 0 : return -1;
550 : : }
551 : :
552 [ # # ]: 0 : if (drv->drv_type == dev->device_type)
553 : 0 : return 0;
554 : :
555 : : return -1;
556 : : }
557 : :
558 : : static int
559 : 0 : rte_dpaa_bus_dev_build(void)
560 : : {
561 : : int ret;
562 : :
563 : : /* Load the device-tree driver */
564 : : ret = of_init();
565 [ # # ]: 0 : if (ret) {
566 : 0 : DPAA_BUS_LOG(ERR, "of_init failed with ret: %d", ret);
567 : 0 : return -1;
568 : : }
569 : :
570 : : /* Get the interface configurations from device-tree */
571 : 0 : dpaa_netcfg = netcfg_acquire();
572 [ # # ]: 0 : if (!dpaa_netcfg) {
573 : 0 : DPAA_BUS_LOG(ERR,
574 : : "netcfg failed: /dev/fsl_usdpaa device not available");
575 : 0 : DPAA_BUS_WARN(
576 : : "Check if you are using USDPAA based device tree");
577 : 0 : return -EINVAL;
578 : : }
579 : :
580 : 0 : RTE_LOG(NOTICE, EAL, "DPAA Bus Detected\n");
581 : :
582 [ # # ]: 0 : if (!dpaa_netcfg->num_ethports) {
583 : 0 : DPAA_BUS_LOG(INFO, "NO DPDK mapped net interfaces available");
584 : : /* This is not an error */
585 : : }
586 : :
587 : : #ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER
588 : : dump_netcfg(dpaa_netcfg);
589 : : #endif
590 : :
591 : 0 : DPAA_BUS_LOG(DEBUG, "Number of ethernet devices = %d",
592 : : dpaa_netcfg->num_ethports);
593 : 0 : ret = dpaa_create_device_list();
594 [ # # ]: 0 : if (ret) {
595 : 0 : DPAA_BUS_LOG(ERR, "Unable to create device list. (%d)", ret);
596 : 0 : return ret;
597 : : }
598 : : return 0;
599 : : }
600 : :
601 : 0 : static int rte_dpaa_setup_intr(struct rte_intr_handle *intr_handle)
602 : : {
603 : : int fd;
604 : :
605 : 0 : fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
606 [ # # ]: 0 : if (fd < 0) {
607 : 0 : DPAA_BUS_ERR("Cannot set up eventfd, error %i (%s)",
608 : : errno, strerror(errno));
609 : 0 : return errno;
610 : : }
611 : :
612 [ # # ]: 0 : if (rte_intr_fd_set(intr_handle, fd))
613 : 0 : return rte_errno;
614 : :
615 [ # # ]: 0 : if (rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_EXT))
616 : 0 : return rte_errno;
617 : :
618 : : return 0;
619 : : }
620 : :
621 : : static int
622 : 164 : rte_dpaa_bus_probe(void)
623 : : {
624 : : int ret = -1;
625 : : struct rte_dpaa_device *dev;
626 : : struct rte_dpaa_driver *drv;
627 : : FILE *svr_file = NULL;
628 : : unsigned int svr_ver;
629 : 164 : int probe_all = rte_dpaa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_ALLOWLIST;
630 : : static int process_once;
631 : :
632 : : /* If DPAA bus is not present nothing needs to be done */
633 [ - + ]: 164 : if (!rte_dpaa_bus.detected)
634 : : return 0;
635 : :
636 : : /* Device list creation is only done once */
637 [ # # ]: 0 : if (!process_once) {
638 : 0 : rte_dpaa_bus_dev_build();
639 : : /* One time load of Qman/Bman drivers */
640 : 0 : ret = qman_global_init();
641 [ # # ]: 0 : if (ret) {
642 : 0 : DPAA_BUS_ERR("QMAN initialization failed: %d",
643 : : ret);
644 : 0 : return ret;
645 : : }
646 : 0 : ret = bman_global_init();
647 [ # # ]: 0 : if (ret) {
648 : 0 : DPAA_BUS_ERR("BMAN initialization failed: %d",
649 : : ret);
650 : 0 : return ret;
651 : : }
652 : : }
653 : 0 : process_once = 1;
654 : :
655 : : /* If no device present on DPAA bus nothing needs to be done */
656 [ # # ]: 0 : if (TAILQ_EMPTY(&rte_dpaa_bus.device_list))
657 : : return 0;
658 : :
659 : : /* Register DPAA mempool ops only if any DPAA device has
660 : : * been detected.
661 : : */
662 : 0 : rte_mbuf_set_platform_mempool_ops(DPAA_MEMPOOL_OPS_NAME);
663 : :
664 : 0 : svr_file = fopen(DPAA_SOC_ID_FILE, "r");
665 [ # # ]: 0 : if (svr_file) {
666 [ # # ]: 0 : if (fscanf(svr_file, "svr:%x", &svr_ver) > 0)
667 : 0 : dpaa_svr_family = svr_ver & SVR_MASK;
668 : 0 : fclose(svr_file);
669 : : }
670 : :
671 [ # # ]: 0 : TAILQ_FOREACH(dev, &rte_dpaa_bus.device_list, next) {
672 [ # # ]: 0 : if (dev->device_type == FSL_DPAA_ETH) {
673 : 0 : ret = rte_dpaa_setup_intr(dev->intr_handle);
674 [ # # ]: 0 : if (ret)
675 : 0 : DPAA_BUS_ERR("Error setting up interrupt.\n");
676 : : }
677 : : }
678 : :
679 : : /* And initialize the PA->VA translation table */
680 : 0 : dpaax_iova_table_populate();
681 : :
682 : : /* For each registered driver, and device, call the driver->probe */
683 [ # # ]: 0 : TAILQ_FOREACH(dev, &rte_dpaa_bus.device_list, next) {
684 [ # # ]: 0 : TAILQ_FOREACH(drv, &rte_dpaa_bus.driver_list, next) {
685 : 0 : ret = rte_dpaa_device_match(drv, dev);
686 [ # # ]: 0 : if (ret)
687 : 0 : continue;
688 : :
689 [ # # ]: 0 : if (rte_dev_is_probed(&dev->device))
690 : 0 : continue;
691 : :
692 [ # # ]: 0 : if (!drv->probe ||
693 [ # # ]: 0 : (dev->device.devargs &&
694 [ # # ]: 0 : dev->device.devargs->policy == RTE_DEV_BLOCKED))
695 : 0 : continue;
696 : :
697 [ # # # # ]: 0 : if (probe_all ||
698 : 0 : (dev->device.devargs &&
699 [ # # ]: 0 : dev->device.devargs->policy == RTE_DEV_ALLOWED)) {
700 : 0 : ret = drv->probe(drv, dev);
701 [ # # ]: 0 : if (ret) {
702 : 0 : DPAA_BUS_ERR("unable to probe:%s",
703 : : dev->name);
704 : : } else {
705 : 0 : dev->driver = drv;
706 : 0 : dev->device.driver = &drv->driver;
707 : : }
708 : : }
709 : : break;
710 : : }
711 : : }
712 : :
713 : : return 0;
714 : : }
715 : :
716 : : static struct rte_device *
717 : 0 : rte_dpaa_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
718 : : const void *data)
719 : : {
720 : : struct rte_dpaa_device *dev;
721 : : const struct rte_dpaa_device *dstart;
722 : :
723 : : /* find_device is called with 'data' as an opaque object - just call
724 : : * cmp with this and each device object on bus.
725 : : */
726 : :
727 [ # # ]: 0 : if (start != NULL) {
728 : 0 : dstart = RTE_DEV_TO_DPAA_CONST(start);
729 : 0 : dev = TAILQ_NEXT(dstart, next);
730 : : } else {
731 : 0 : dev = TAILQ_FIRST(&rte_dpaa_bus.device_list);
732 : : }
733 : :
734 [ # # ]: 0 : while (dev != NULL) {
735 [ # # ]: 0 : if (cmp(&dev->device, data) == 0) {
736 : 0 : DPAA_BUS_DEBUG("Found dev=(%s)\n", dev->device.name);
737 : 0 : return &dev->device;
738 : : }
739 : 0 : dev = TAILQ_NEXT(dev, next);
740 : : }
741 : :
742 : 0 : DPAA_BUS_DEBUG("Unable to find any device\n");
743 : 0 : return NULL;
744 : : }
745 : :
746 : : /*
747 : : * Get iommu class of DPAA2 devices on the bus.
748 : : */
749 : : static enum rte_iova_mode
750 : 169 : rte_dpaa_get_iommu_class(void)
751 : : {
752 [ + - + - ]: 338 : if ((access(DPAA_DEV_PATH1, F_OK) != 0) &&
753 : 169 : (access(DPAA_DEV_PATH2, F_OK) != 0)) {
754 : 169 : return RTE_IOVA_DC;
755 : : }
756 : : return RTE_IOVA_PA;
757 : : }
758 : :
759 : : static int
760 : 0 : dpaa_bus_plug(struct rte_device *dev __rte_unused)
761 : : {
762 : : /* No operation is performed while plugging the device */
763 : 0 : return 0;
764 : : }
765 : :
766 : : static int
767 : 0 : dpaa_bus_unplug(struct rte_device *dev __rte_unused)
768 : : {
769 : : /* No operation is performed while unplugging the device */
770 : 0 : return 0;
771 : : }
772 : :
773 : : static void *
774 : 0 : dpaa_bus_dev_iterate(const void *start, const char *str,
775 : : const struct rte_dev_iterator *it __rte_unused)
776 : : {
777 : : const struct rte_dpaa_device *dstart;
778 : : struct rte_dpaa_device *dev;
779 : : char *dup, *dev_name = NULL;
780 : :
781 [ # # ]: 0 : if (str == NULL) {
782 : 0 : DPAA_BUS_DEBUG("No device string");
783 : 0 : return NULL;
784 : : }
785 : :
786 : : /* Expectation is that device would be name=device_name */
787 [ # # ]: 0 : if (strncmp(str, "name=", 5) != 0) {
788 : 0 : DPAA_BUS_DEBUG("Invalid device string (%s)\n", str);
789 : 0 : return NULL;
790 : : }
791 : :
792 : : /* Now that name=device_name format is available, split */
793 : 0 : dup = strdup(str);
794 : 0 : dev_name = dup + strlen("name=");
795 : :
796 [ # # ]: 0 : if (start != NULL) {
797 : 0 : dstart = RTE_DEV_TO_DPAA_CONST(start);
798 : 0 : dev = TAILQ_NEXT(dstart, next);
799 : : } else {
800 : 0 : dev = TAILQ_FIRST(&rte_dpaa_bus.device_list);
801 : : }
802 : :
803 [ # # ]: 0 : while (dev != NULL) {
804 [ # # ]: 0 : if (strcmp(dev->device.name, dev_name) == 0) {
805 : 0 : free(dup);
806 : 0 : return &dev->device;
807 : : }
808 : 0 : dev = TAILQ_NEXT(dev, next);
809 : : }
810 : :
811 : 0 : free(dup);
812 : 0 : return NULL;
813 : : }
814 : :
815 : : static struct rte_dpaa_bus rte_dpaa_bus = {
816 : : .bus = {
817 : : .scan = rte_dpaa_bus_scan,
818 : : .probe = rte_dpaa_bus_probe,
819 : : .parse = rte_dpaa_bus_parse,
820 : : .find_device = rte_dpaa_find_device,
821 : : .get_iommu_class = rte_dpaa_get_iommu_class,
822 : : .plug = dpaa_bus_plug,
823 : : .unplug = dpaa_bus_unplug,
824 : : .dev_iterate = dpaa_bus_dev_iterate,
825 : : },
826 : : .device_list = TAILQ_HEAD_INITIALIZER(rte_dpaa_bus.device_list),
827 : : .driver_list = TAILQ_HEAD_INITIALIZER(rte_dpaa_bus.driver_list),
828 : : .device_count = 0,
829 : : };
830 : :
831 : 235 : RTE_REGISTER_BUS(FSL_DPAA_BUS_NAME, rte_dpaa_bus.bus);
832 [ - + ]: 235 : RTE_LOG_REGISTER_DEFAULT(dpaa_logtype_bus, NOTICE);
|