event/dpaa2: initialize device
[dpdk.git] / drivers / event / dpaa2 / dpaa2_eventdev.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright 2017 NXP.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of NXP nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <assert.h>
34 #include <stdio.h>
35 #include <stdbool.h>
36 #include <errno.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <stdint.h>
40 #include <sys/epoll.h>
41
42 #include <rte_atomic.h>
43 #include <rte_byteorder.h>
44 #include <rte_common.h>
45 #include <rte_debug.h>
46 #include <rte_dev.h>
47 #include <rte_eal.h>
48 #include <rte_fslmc.h>
49 #include <rte_lcore.h>
50 #include <rte_log.h>
51 #include <rte_malloc.h>
52 #include <rte_memory.h>
53 #include <rte_memzone.h>
54 #include <rte_pci.h>
55 #include <rte_vdev.h>
56
57 #include <fslmc_vfio.h>
58 #include <dpaa2_hw_pvt.h>
59 #include <dpaa2_hw_mempool.h>
60 #include <dpaa2_hw_dpio.h>
61 #include "dpaa2_eventdev.h"
62 #include <portal/dpaa2_hw_pvt.h>
63 #include <mc/fsl_dpci.h>
64
65 /* Clarifications
66  * Evendev = SoC Instance
67  * Eventport = DPIO Instance
68  * Eventqueue = DPCON Instance
69  * 1 Eventdev can have N Eventqueue
70  * Soft Event Flow is DPCI Instance
71  */
72
73 static uint16_t
74 dpaa2_eventdev_enqueue_burst(void *port, const struct rte_event ev[],
75                              uint16_t nb_events)
76 {
77         RTE_SET_USED(port);
78         RTE_SET_USED(ev);
79         RTE_SET_USED(nb_events);
80
81         return 0;
82 }
83
84 static uint16_t
85 dpaa2_eventdev_enqueue(void *port, const struct rte_event *ev)
86 {
87         return dpaa2_eventdev_enqueue_burst(port, ev, 1);
88 }
89
90 static uint16_t
91 dpaa2_eventdev_dequeue_burst(void *port, struct rte_event ev[],
92                              uint16_t nb_events, uint64_t timeout_ticks)
93 {
94         RTE_SET_USED(port);
95         RTE_SET_USED(ev);
96         RTE_SET_USED(nb_events);
97         RTE_SET_USED(timeout_ticks);
98
99         return 0;
100 }
101
102 static uint16_t
103 dpaa2_eventdev_dequeue(void *port, struct rte_event *ev,
104                        uint64_t timeout_ticks)
105 {
106         return dpaa2_eventdev_dequeue_burst(port, ev, 1, timeout_ticks);
107 }
108
109 static const struct rte_eventdev_ops dpaa2_eventdev_ops;
110
111 static int
112 dpaa2_eventdev_setup_dpci(struct dpaa2_dpci_dev *dpci_dev,
113                           struct dpaa2_dpcon_dev *dpcon_dev)
114 {
115         struct dpci_rx_queue_cfg rx_queue_cfg;
116         int ret, i;
117
118         /*Do settings to get the frame on a DPCON object*/
119         rx_queue_cfg.options = DPCI_QUEUE_OPT_DEST;
120         rx_queue_cfg.dest_cfg.dest_type = DPCI_DEST_DPCON;
121         rx_queue_cfg.dest_cfg.dest_id = dpcon_dev->dpcon_id;
122         rx_queue_cfg.dest_cfg.priority = DPAA2_EVENT_DEFAULT_DPCI_PRIO;
123
124         for (i = 0 ; i < DPAA2_EVENT_DPCI_MAX_QUEUES; i++) {
125                 rx_queue_cfg.user_ctx = (uint64_t)(&dpci_dev->queue[i]);
126                 ret = dpci_set_rx_queue(&dpci_dev->dpci,
127                                         CMD_PRI_LOW,
128                                         dpci_dev->token, i,
129                                         &rx_queue_cfg);
130                 if (ret) {
131                         PMD_DRV_LOG(ERR, PMD,
132                                     "set_rx_q failed with err code: %d", ret);
133                         return ret;
134                 }
135         }
136         return 0;
137 }
138
139 static int
140 dpaa2_eventdev_create(const char *name)
141 {
142         struct rte_eventdev *eventdev;
143         struct dpaa2_eventdev *priv;
144         struct dpaa2_dpcon_dev *dpcon_dev = NULL;
145         struct dpaa2_dpci_dev *dpci_dev = NULL;
146         int ret;
147
148         eventdev = rte_event_pmd_vdev_init(name,
149                                            sizeof(struct dpaa2_eventdev),
150                                            rte_socket_id());
151         if (eventdev == NULL) {
152                 PMD_DRV_ERR("Failed to create eventdev vdev %s", name);
153                 goto fail;
154         }
155
156         eventdev->dev_ops       = &dpaa2_eventdev_ops;
157         eventdev->schedule      = NULL;
158         eventdev->enqueue       = dpaa2_eventdev_enqueue;
159         eventdev->enqueue_burst = dpaa2_eventdev_enqueue_burst;
160         eventdev->dequeue       = dpaa2_eventdev_dequeue;
161         eventdev->dequeue_burst = dpaa2_eventdev_dequeue_burst;
162
163         /* For secondary processes, the primary has done all the work */
164         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
165                 return 0;
166
167         priv = eventdev->data->dev_private;
168         priv->max_event_queues = 0;
169
170         do {
171                 dpcon_dev = rte_dpaa2_alloc_dpcon_dev();
172                 if (!dpcon_dev)
173                         break;
174                 priv->evq_info[priv->max_event_queues].dpcon = dpcon_dev;
175
176                 dpci_dev = rte_dpaa2_alloc_dpci_dev();
177                 if (!dpci_dev) {
178                         rte_dpaa2_free_dpcon_dev(dpcon_dev);
179                         break;
180                 }
181                 priv->evq_info[priv->max_event_queues].dpci = dpci_dev;
182
183                 ret = dpaa2_eventdev_setup_dpci(dpci_dev, dpcon_dev);
184                 if (ret) {
185                         PMD_DRV_LOG(ERR, PMD,
186                                     "dpci setup failed with err code: %d", ret);
187                         return ret;
188                 }
189                 priv->max_event_queues++;
190         } while (dpcon_dev && dpci_dev);
191
192         return 0;
193 fail:
194         return -EFAULT;
195 }
196
197 static int
198 dpaa2_eventdev_probe(struct rte_vdev_device *vdev)
199 {
200         const char *name;
201
202         name = rte_vdev_device_name(vdev);
203         PMD_DRV_LOG(INFO, PMD, "Initializing %s\n", name);
204         return dpaa2_eventdev_create(name);
205 }
206
207 static int
208 dpaa2_eventdev_remove(struct rte_vdev_device *vdev)
209 {
210         const char *name;
211
212         name = rte_vdev_device_name(vdev);
213         PMD_DRV_LOG(INFO, "Closing %s", name);
214
215         return rte_event_pmd_vdev_uninit(name);
216 }
217
218 static struct rte_vdev_driver vdev_eventdev_dpaa2_pmd = {
219         .probe = dpaa2_eventdev_probe,
220         .remove = dpaa2_eventdev_remove
221 };
222
223 RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_DPAA2_PMD, vdev_eventdev_dpaa2_pmd);