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