raw/dpaa2_cmdif: introduce DPAA2 command interface driver
[dpdk.git] / drivers / raw / dpaa2_cmdif / dpaa2_cmdif.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2018 NXP
3  */
4
5 #include <stdio.h>
6 #include <errno.h>
7 #include <stdint.h>
8
9 #include <rte_bus_vdev.h>
10 #include <rte_atomic.h>
11 #include <rte_interrupts.h>
12 #include <rte_branch_prediction.h>
13 #include <rte_lcore.h>
14
15 #include <rte_rawdev.h>
16 #include <rte_rawdev_pmd.h>
17
18 #include <portal/dpaa2_hw_pvt.h>
19 #include <portal/dpaa2_hw_dpio.h>
20 #include "dpaa2_cmdif_logs.h"
21
22 /* Dynamic log type identifier */
23 int dpaa2_cmdif_logtype;
24
25 /* CMDIF driver name */
26 #define DPAA2_CMDIF_PMD_NAME dpaa2_dpci
27
28 /* CMDIF driver object */
29 static struct rte_vdev_driver dpaa2_cmdif_drv;
30
31 static const struct rte_rawdev_ops dpaa2_cmdif_ops;
32
33 static int
34 dpaa2_cmdif_create(const char *name,
35                    struct rte_vdev_device *vdev,
36                    int socket_id)
37 {
38         struct rte_rawdev *rawdev;
39         struct dpaa2_dpci_dev *cidev;
40
41         /* Allocate device structure */
42         rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct dpaa2_dpci_dev),
43                                          socket_id);
44         if (!rawdev) {
45                 DPAA2_CMDIF_ERR("Unable to allocate rawdevice");
46                 return -EINVAL;
47         }
48
49         rawdev->dev_ops = &dpaa2_cmdif_ops;
50         rawdev->device = &vdev->device;
51         rawdev->driver_name = vdev->device.driver->name;
52
53         /* For secondary processes, the primary has done all the work */
54         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
55                 return 0;
56
57         cidev = rte_dpaa2_alloc_dpci_dev();
58         if (!cidev) {
59                 DPAA2_CMDIF_ERR("Unable to allocate CI device");
60                 rte_rawdev_pmd_release(rawdev);
61                 return -ENODEV;
62         }
63
64         rawdev->dev_private = cidev;
65
66         return 0;
67 }
68
69 static int
70 dpaa2_cmdif_destroy(const char *name)
71 {
72         int ret;
73         struct rte_rawdev *rdev;
74
75         rdev = rte_rawdev_pmd_get_named_dev(name);
76         if (!rdev) {
77                 DPAA2_CMDIF_ERR("Invalid device name (%s)", name);
78                 return -EINVAL;
79         }
80
81         /* The primary process will only free the DPCI device */
82         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
83                 rte_dpaa2_free_dpci_dev(rdev->dev_private);
84
85         ret = rte_rawdev_pmd_release(rdev);
86         if (ret)
87                 DPAA2_CMDIF_DEBUG("Device cleanup failed");
88
89         return 0;
90 }
91
92 static int
93 dpaa2_cmdif_probe(struct rte_vdev_device *vdev)
94 {
95         const char *name;
96         int ret = 0;
97
98         name = rte_vdev_device_name(vdev);
99
100         DPAA2_CMDIF_INFO("Init %s on NUMA node %d", name, rte_socket_id());
101
102         ret = dpaa2_cmdif_create(name, vdev, rte_socket_id());
103
104         return ret;
105 }
106
107 static int
108 dpaa2_cmdif_remove(struct rte_vdev_device *vdev)
109 {
110         const char *name;
111         int ret;
112
113         name = rte_vdev_device_name(vdev);
114
115         DPAA2_CMDIF_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
116
117         ret = dpaa2_cmdif_destroy(name);
118
119         return ret;
120 }
121
122 static struct rte_vdev_driver dpaa2_cmdif_drv = {
123         .probe = dpaa2_cmdif_probe,
124         .remove = dpaa2_cmdif_remove
125 };
126
127 RTE_PMD_REGISTER_VDEV(DPAA2_CMDIF_PMD_NAME, dpaa2_cmdif_drv);
128
129 RTE_INIT(dpaa2_cmdif_init_log);
130
131 static void
132 dpaa2_cmdif_init_log(void)
133 {
134         dpaa2_cmdif_logtype = rte_log_register("pmd.raw.dpaa2.cmdif");
135         if (dpaa2_cmdif_logtype >= 0)
136                 rte_log_set_level(dpaa2_cmdif_logtype, RTE_LOG_INFO);
137 }