75a14ac1ea851554e729050d34f32cec5dedcb74
[dpdk.git] / lib / librte_eventdev / rte_event_timer_adapter.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017-2018 Intel Corporation.
3  * All rights reserved.
4  */
5
6 #include <string.h>
7 #include <inttypes.h>
8
9 #include <rte_memzone.h>
10 #include <rte_memory.h>
11 #include <rte_dev.h>
12 #include <rte_errno.h>
13
14 #include "rte_eventdev.h"
15 #include "rte_eventdev_pmd.h"
16 #include "rte_event_timer_adapter.h"
17 #include "rte_event_timer_adapter_pmd.h"
18
19 #define DATA_MZ_NAME_MAX_LEN 64
20 #define DATA_MZ_NAME_FORMAT "rte_event_timer_adapter_data_%d"
21
22 static int evtim_logtype;
23
24 static struct rte_event_timer_adapter adapters[RTE_EVENT_TIMER_ADAPTER_NUM_MAX];
25
26 #define EVTIM_LOG(level, logtype, ...) \
27         rte_log(RTE_LOG_ ## level, logtype, \
28                 RTE_FMT("EVTIMER: %s() line %u: " RTE_FMT_HEAD(__VA_ARGS__,) \
29                         "\n", __func__, __LINE__, RTE_FMT_TAIL(__VA_ARGS__,)))
30
31 #define EVTIM_LOG_ERR(...) EVTIM_LOG(ERR, evtim_logtype, __VA_ARGS__)
32
33 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
34 #define EVTIM_LOG_DBG(...) \
35         EVTIM_LOG(DEBUG, evtim_logtype, __VA_ARGS__)
36 #else
37 #define EVTIM_LOG_DBG(...) (void)0
38 #endif
39
40 static int
41 default_port_conf_cb(uint16_t id, uint8_t event_dev_id, uint8_t *event_port_id,
42                      void *conf_arg)
43 {
44         struct rte_event_timer_adapter *adapter;
45         struct rte_eventdev *dev;
46         struct rte_event_dev_config dev_conf;
47         struct rte_event_port_conf *port_conf, def_port_conf = {0};
48         int started;
49         uint8_t port_id;
50         uint8_t dev_id;
51         int ret;
52
53         RTE_SET_USED(event_dev_id);
54
55         adapter = &adapters[id];
56         dev = &rte_eventdevs[adapter->data->event_dev_id];
57         dev_id = dev->data->dev_id;
58         dev_conf = dev->data->dev_conf;
59
60         started = dev->data->dev_started;
61         if (started)
62                 rte_event_dev_stop(dev_id);
63
64         port_id = dev_conf.nb_event_ports;
65         dev_conf.nb_event_ports += 1;
66         ret = rte_event_dev_configure(dev_id, &dev_conf);
67         if (ret < 0) {
68                 EVTIM_LOG_ERR("failed to configure event dev %u\n", dev_id);
69                 if (started)
70                         if (rte_event_dev_start(dev_id))
71                                 return -EIO;
72
73                 return ret;
74         }
75
76         if (conf_arg != NULL)
77                 port_conf = conf_arg;
78         else {
79                 port_conf = &def_port_conf;
80                 ret = rte_event_port_default_conf_get(dev_id, port_id,
81                                                       port_conf);
82                 if (ret < 0)
83                         return ret;
84         }
85
86         ret = rte_event_port_setup(dev_id, port_id, port_conf);
87         if (ret < 0) {
88                 EVTIM_LOG_ERR("failed to setup event port %u on event dev %u\n",
89                               port_id, dev_id);
90                 return ret;
91         }
92
93         *event_port_id = port_id;
94
95         if (started)
96                 ret = rte_event_dev_start(dev_id);
97
98         return ret;
99 }
100
101 struct rte_event_timer_adapter * __rte_experimental
102 rte_event_timer_adapter_create(const struct rte_event_timer_adapter_conf *conf)
103 {
104         return rte_event_timer_adapter_create_ext(conf, default_port_conf_cb,
105                                                   NULL);
106 }
107
108 struct rte_event_timer_adapter * __rte_experimental
109 rte_event_timer_adapter_create_ext(
110                 const struct rte_event_timer_adapter_conf *conf,
111                 rte_event_timer_adapter_port_conf_cb_t conf_cb,
112                 void *conf_arg)
113 {
114         uint16_t adapter_id;
115         struct rte_event_timer_adapter *adapter;
116         const struct rte_memzone *mz;
117         char mz_name[DATA_MZ_NAME_MAX_LEN];
118         int n, ret;
119         struct rte_eventdev *dev;
120
121         if (conf == NULL) {
122                 rte_errno = EINVAL;
123                 return NULL;
124         }
125
126         /* Check eventdev ID */
127         if (!rte_event_pmd_is_valid_dev(conf->event_dev_id)) {
128                 rte_errno = EINVAL;
129                 return NULL;
130         }
131         dev = &rte_eventdevs[conf->event_dev_id];
132
133         adapter_id = conf->timer_adapter_id;
134
135         /* Check that adapter_id is in range */
136         if (adapter_id >= RTE_EVENT_TIMER_ADAPTER_NUM_MAX) {
137                 rte_errno = EINVAL;
138                 return NULL;
139         }
140
141         /* Check adapter ID not already allocated */
142         adapter = &adapters[adapter_id];
143         if (adapter->allocated) {
144                 rte_errno = EEXIST;
145                 return NULL;
146         }
147
148         /* Create shared data area. */
149         n = snprintf(mz_name, sizeof(mz_name), DATA_MZ_NAME_FORMAT, adapter_id);
150         if (n >= (int)sizeof(mz_name)) {
151                 rte_errno = EINVAL;
152                 return NULL;
153         }
154         mz = rte_memzone_reserve(mz_name,
155                                  sizeof(struct rte_event_timer_adapter_data),
156                                  conf->socket_id, 0);
157         if (mz == NULL)
158                 /* rte_errno set by rte_memzone_reserve */
159                 return NULL;
160
161         adapter->data = mz->addr;
162         memset(adapter->data, 0, sizeof(struct rte_event_timer_adapter_data));
163
164         adapter->data->mz = mz;
165         adapter->data->event_dev_id = conf->event_dev_id;
166         adapter->data->id = adapter_id;
167         adapter->data->socket_id = conf->socket_id;
168         adapter->data->conf = *conf;  /* copy conf structure */
169
170         /* Query eventdev PMD for timer adapter capabilities and ops */
171         ret = dev->dev_ops->timer_adapter_caps_get(dev,
172                                                    adapter->data->conf.flags,
173                                                    &adapter->data->caps,
174                                                    &adapter->ops);
175         if (ret < 0) {
176                 rte_errno = ret;
177                 goto free_memzone;
178         }
179
180         if (!(adapter->data->caps &
181               RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) {
182                 FUNC_PTR_OR_NULL_RET_WITH_ERRNO(conf_cb, -EINVAL);
183                 ret = conf_cb(adapter->data->id, adapter->data->event_dev_id,
184                               &adapter->data->event_port_id, conf_arg);
185                 if (ret < 0) {
186                         rte_errno = ret;
187                         goto free_memzone;
188                 }
189         }
190
191         /* Allow driver to do some setup */
192         FUNC_PTR_OR_NULL_RET_WITH_ERRNO(adapter->ops->init, -ENOTSUP);
193         ret = adapter->ops->init(adapter);
194         if (ret < 0) {
195                 rte_errno = ret;
196                 goto free_memzone;
197         }
198
199         /* Set fast-path function pointers */
200         adapter->arm_burst = adapter->ops->arm_burst;
201         adapter->arm_tmo_tick_burst = adapter->ops->arm_tmo_tick_burst;
202         adapter->cancel_burst = adapter->ops->cancel_burst;
203
204         adapter->allocated = 1;
205
206         return adapter;
207
208 free_memzone:
209         rte_memzone_free(adapter->data->mz);
210         return NULL;
211 }
212
213 int __rte_experimental
214 rte_event_timer_adapter_get_info(const struct rte_event_timer_adapter *adapter,
215                 struct rte_event_timer_adapter_info *adapter_info)
216 {
217         ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
218
219         if (adapter->ops->get_info)
220                 /* let driver set values it knows */
221                 adapter->ops->get_info(adapter, adapter_info);
222
223         /* Set common values */
224         adapter_info->conf = adapter->data->conf;
225         adapter_info->event_dev_port_id = adapter->data->event_port_id;
226         adapter_info->caps = adapter->data->caps;
227
228         return 0;
229 }
230
231 int __rte_experimental
232 rte_event_timer_adapter_start(const struct rte_event_timer_adapter *adapter)
233 {
234         int ret;
235
236         ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
237         FUNC_PTR_OR_ERR_RET(adapter->ops->start, -EINVAL);
238
239         ret = adapter->ops->start(adapter);
240         if (ret < 0)
241                 return ret;
242
243         adapter->data->started = 1;
244
245         return 0;
246 }
247
248 int __rte_experimental
249 rte_event_timer_adapter_stop(const struct rte_event_timer_adapter *adapter)
250 {
251         int ret;
252
253         ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
254         FUNC_PTR_OR_ERR_RET(adapter->ops->stop, -EINVAL);
255
256         if (adapter->data->started == 0) {
257                 EVTIM_LOG_ERR("event timer adapter %"PRIu8" already stopped",
258                               adapter->data->id);
259                 return 0;
260         }
261
262         ret = adapter->ops->stop(adapter);
263         if (ret < 0)
264                 return ret;
265
266         adapter->data->started = 0;
267
268         return 0;
269 }
270
271 struct rte_event_timer_adapter * __rte_experimental
272 rte_event_timer_adapter_lookup(uint16_t adapter_id)
273 {
274         char name[DATA_MZ_NAME_MAX_LEN];
275         const struct rte_memzone *mz;
276         struct rte_event_timer_adapter_data *data;
277         struct rte_event_timer_adapter *adapter;
278         int ret;
279         struct rte_eventdev *dev;
280
281         if (adapters[adapter_id].allocated)
282                 return &adapters[adapter_id]; /* Adapter is already loaded */
283
284         snprintf(name, DATA_MZ_NAME_MAX_LEN, DATA_MZ_NAME_FORMAT, adapter_id);
285         mz = rte_memzone_lookup(name);
286         if (mz == NULL) {
287                 rte_errno = ENOENT;
288                 return NULL;
289         }
290
291         data = mz->addr;
292
293         adapter = &adapters[data->id];
294         adapter->data = data;
295
296         dev = &rte_eventdevs[adapter->data->event_dev_id];
297
298         /* Query eventdev PMD for timer adapter capabilities and ops */
299         ret = dev->dev_ops->timer_adapter_caps_get(dev,
300                                                    adapter->data->conf.flags,
301                                                    &adapter->data->caps,
302                                                    &adapter->ops);
303         if (ret < 0) {
304                 rte_errno = EINVAL;
305                 return NULL;
306         }
307
308         /* Set fast-path function pointers */
309         adapter->arm_burst = adapter->ops->arm_burst;
310         adapter->arm_tmo_tick_burst = adapter->ops->arm_tmo_tick_burst;
311         adapter->cancel_burst = adapter->ops->cancel_burst;
312
313         adapter->allocated = 1;
314
315         return adapter;
316 }
317
318 int __rte_experimental
319 rte_event_timer_adapter_free(struct rte_event_timer_adapter *adapter)
320 {
321         int ret;
322
323         ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
324         FUNC_PTR_OR_ERR_RET(adapter->ops->uninit, -EINVAL);
325
326         if (adapter->data->started == 1) {
327                 EVTIM_LOG_ERR("event timer adapter %"PRIu8" must be stopped "
328                               "before freeing", adapter->data->id);
329                 return -EBUSY;
330         }
331
332         /* free impl priv data */
333         ret = adapter->ops->uninit(adapter);
334         if (ret < 0)
335                 return ret;
336
337         /* free shared data area */
338         ret = rte_memzone_free(adapter->data->mz);
339         if (ret < 0)
340                 return ret;
341
342         adapter->data = NULL;
343         adapter->allocated = 0;
344
345         return 0;
346 }
347
348 int __rte_experimental
349 rte_event_timer_adapter_service_id_get(struct rte_event_timer_adapter *adapter,
350                                        uint32_t *service_id)
351 {
352         ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
353
354         if (adapter->data->service_inited && service_id != NULL)
355                 *service_id = adapter->data->service_id;
356
357         return adapter->data->service_inited ? 0 : -ESRCH;
358 }
359
360 int __rte_experimental
361 rte_event_timer_adapter_stats_get(struct rte_event_timer_adapter *adapter,
362                                   struct rte_event_timer_adapter_stats *stats)
363 {
364         ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
365         FUNC_PTR_OR_ERR_RET(adapter->ops->stats_get, -EINVAL);
366         if (stats == NULL)
367                 return -EINVAL;
368
369         return adapter->ops->stats_get(adapter, stats);
370 }
371
372 int __rte_experimental
373 rte_event_timer_adapter_stats_reset(struct rte_event_timer_adapter *adapter)
374 {
375         ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
376         FUNC_PTR_OR_ERR_RET(adapter->ops->stats_reset, -EINVAL);
377         return adapter->ops->stats_reset(adapter);
378 }
379
380 RTE_INIT(event_timer_adapter_init_log);
381 static void
382 event_timer_adapter_init_log(void)
383 {
384         evtim_logtype = rte_log_register("lib.eventdev.adapter.timer");
385         if (evtim_logtype >= 0)
386                 rte_log_set_level(evtim_logtype, RTE_LOG_NOTICE);
387 }