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